以下是为与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的直接翻译......
答案 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();
}