0

以下は、EntityFrameworkで使用するように設計された汎用リポジトリの実装です。この演習では、その「良さ」または「悪さ」を無視します。

NHibernateでのこのコードはどのようになりますか?

乾杯、
ベリール

public class Repository<T> : IRepository<T> 
where T : class
{
protected ObjectContext Context;
protected ObjectSet<T> QueryBase;

public Repository(ObjectContext context)
{
    Context = context;
    QueryBase = context.CreateObjectSet<T>();
}

public IEnumerable<T> Matches(ICriteria<T> criteria)
{
    var query = criteria.BuildQueryFrom(QueryBase);
    return query.ToList();
}

public void Save(T entity)
{
    QueryBase.AddObject(entity);
}

ノート

これは、リポジトリを設計する方法や、リポジトリを使用するかどうかについての質問ではありません。EFからNHibへの単純な翻訳...

4

2 に答える 2

1

リポジトリのNhibバージョンはISessionオブジェクトになります。ayendeからの
この有名な投稿を参照してください。

于 2012-11-05T20:34:39.100 に答える
0

リポジトリは次のようになります

public abstract class Repository<TEntity> : IRepository<TEntity>
        where TEntity : Entity
    {
        #region Members

        protected IContext Context;

        #endregion

        #region Constructor

        /// <summary>
        /// Create a new instance of repository
        /// </summary>
        /// <param name="context">Associated Unit Of Work</param>
        protected Repository(IContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            Context = context;
        }

        #endregion

        #region IRepository Members

        public virtual TEntity Add(TEntity item)
        {
            return Context.Add(item);
        }

        public virtual void Remove(TEntity item)
        {
            Set().Remove(item);
        }

        public virtual void Remove(Guid id)
        {
            var persisted = Get(id);

            if (persisted == null) throw new Exception(string.Format("Illegal parameter id:{0}", id));

            Remove(persisted);
        }

        public virtual void Update(TEntity item)
        {
            Context.Update(item);
        }

        public virtual TEntity Get(Guid id)
        {
            return (id != Guid.Empty) ? Query().SingleOrDefault(i => i.Id == id) : null;
        }

        public virtual IEnumerable<TEntity> GetAll()
        {
            return Query();
        }

        public TEntity FirstOrDefaultMatching(ISpecification<TEntity> specification)
        {
            return AllMatching(specification).FirstOrDefault();
        }

        public virtual IEnumerable<TEntity> AllMatching(ISpecification<TEntity> specification)
        {
            return Query().Where(specification.SatisfiedBy());
        }

        public virtual IEnumerable<TEntity> GetPaged<TKProperty>(int pageIndex, int pageCount,
            Expression<Func<TEntity, TKProperty>> orderByExpression, bool ascending)
        {
            var set = Query();

            if (ascending)
            {
                return set.OrderBy(orderByExpression)
                          .Skip(pageCount * pageIndex)
                          .Take(pageCount)
                          .AsEnumerable();
            }

            return set.OrderByDescending(orderByExpression)
                .Skip(pageCount * pageIndex)
                .Take(pageCount)
                .AsEnumerable();
        }

        public virtual IEnumerable<TEntity> GetFiltered(Expression<Func<TEntity, bool>> filter)
        {
            return Query().Where(filter).AsEnumerable();
        }

        public IQueryable<TEntity> CreateSet()
        {
            return Context.CreateSet<TEntity>();
        }

        public bool AnyMatching(ISpecification<TEntity> specification)
        {
            return Query().Any(specification.SatisfiedBy());
        }

        #endregion

        #region Protected Methods

        protected virtual IQueryable<TEntity> Query()
        {
            return Context.CreateSet<TEntity>().Where(EntitySpecification<TEntity>.ValidEntity().SatisfiedBy());
        }

        #endregion
}

EF の場合のコンテキストは DBContext であり、NHibernate の場合は Session です。

これがNHibernateへの私のIContext実装です

public class NHibernateEntityContext : IContext
    {
        private readonly ISession _session;
        private static ISessionFactory _sessionFactory;

        public NHibernateEntityContext()
        {
            if (_sessionFactory == null)
            {
                //Your NHibernate Configuration
                //_sessionFactory = Fluently.Configure()
            }

            _session = _sessionFactory.OpenSession();
            _session.FlushMode = FlushMode.Auto;
        }

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (_session.IsOpen)
                _session.Close();
        }

        #endregion

        public IUnitOfWork BeginTransaction()
        {
            return new UnitOfWork(_session);
        }

        #region Implementation of IContext

        public IQueryable<TEntity> CreateSet<TEntity>() where TEntity : class
        {
            return _exceptionHandler.TryCatch(() => _session.Query<TEntity>());
        }

        /// <summary>
        /// Add this item into the Context
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="item">The item </param>
        public TEntity Add<TEntity>(TEntity item) where TEntity : class
        {
            return _exceptionHandler.TryCatch(() =>
                {
                    _session.Save(item);
                    return item;
                });

            //return _session.Merge(item);
        }

        /// <summary>
        /// Set object as modified
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="item">The entity item to set as modifed</param>
        public void Update<TEntity>(TEntity item) where TEntity : class
        {
            _exceptionHandler.TryCatch(() => _session.Merge(item));
        }

        public void Delete<TEntity>(TEntity item) where TEntity : class
        {
            _exceptionHandler.TryCatch(() => _session.Delete(item));
        }

        #endregion
    }

私のUnitofWorkはこのようなものです

public class UnitOfWork : IUnitOfWork
    {
        private readonly ITransaction _transaction;

        internal UnitOfWork(ISession session)
        {
            _transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);
        }

        public void Commit()
        {
            if (!_transaction.IsActive)
            {
                throw new InvalidOperationException("Oops! We don't have an active transaction");
            }
            _transaction.Commit();
        }

        public void RollbackChanges()
        {
            if (_transaction.IsActive)
            {
                _transaction.Rollback();
            }
        }

        public void Dispose()
        {
            _transaction.Dispose();
        }
    }

そして、次のように使用できます。

using (var trans = UnitOfWorkFactory.Create())
            {
             ...
                trans.Commit();
            }
于 2012-11-05T21:18:55.053 に答える