문제

Below is an implementation for a generic repository desgned for use with Entity Framework. Ignoring its 'goodness' or 'badness' for this exercise...

What would the code look like for this in NHibernate?

Cheers,
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);
}

NOTE

This is NOT a question about how to design a repository or whether to use one or not. Just a straight forward translation from EF to NHib...

도움이 되었습니까?

해결책

the Nhib version of a repository would be an ISession object.
see this famous post from ayende.

다른 팁

The repository could be like this

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
}

The context in the case of EF is the DBContext in NHibernate is the Session

Here is my IContext Implementation to NHibernate

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
    }

My UnitofWork is something like this

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

And you can use it like this:

using (var trans = UnitOfWorkFactory.Create())
            {
             ...
                trans.Commit();
            }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top