the Nhib version of a repository would be an ISession
object.
see this famous post from ayende.
EF repository implementation to NHib
Frage
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...
Lösung
Andere Tipps
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();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow