对NHib的EF存储库实现

时间:2012-11-05 10:47:39

标签: entity-framework nhibernate repository repository-pattern specification-pattern

以下是为与Entity Framework一起使用而设计的通用存储库的实现。忽略了这项练习的“善”或“坏”......

NHibernate中的代码会是什么样的?

干杯,
Berryl

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的直接翻译......

2 个答案:

答案 0 :(得分:1)

存储库的Nhib版本将是ISession对象 见famous post from ayende

答案 1 :(得分: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的情况下的上下文是NHibernate中的DBContext是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
    }

我的单位工作是这样的

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();
            }