我目前正在使用具有通用存储库和工作单元模式的实体框架。我的模型类似于本文中描述的模型
我过去使用过通用存储库,并且非常喜欢它可以提供的全局功能。但是,在将它与 Entity Framework 一起使用时,我似乎每天都遇到更多问题。在处理父/子/连接关系时,这些问题似乎更加突出。
使用带有 EF 的通用存储库开始在我的嘴里留下不好的味道,我开始认为使用带有 EF 的通用存储库是错误的方法。
有人可以帮助我朝着正确的方向前进吗?
我目前正在使用具有通用存储库和工作单元模式的实体框架。我的模型类似于本文中描述的模型
我过去使用过通用存储库,并且非常喜欢它可以提供的全局功能。但是,在将它与 Entity Framework 一起使用时,我似乎每天都遇到更多问题。在处理父/子/连接关系时,这些问题似乎更加突出。
使用带有 EF 的通用存储库开始在我的嘴里留下不好的味道,我开始认为使用带有 EF 的通用存储库是错误的方法。
有人可以帮助我朝着正确的方向前进吗?
这篇文章的方法真的很痛苦,因为您已经在 EF 中拥有了一个通用存储库和一个通用 IUnitOfWork,并且为每种类型创建特定存储库只是消除了通用的好处!
我在这里发布了我如何拥有一个通用存储库和我的 IUnitOfWork 的示例,有了这个你可以拥有一个非常好的存储库!
public interface IUnitOfWork : IDisposable
{
void Save();
void Save(SaveOptions saveOptions);
}
public interface IRepository<TEntity> : IDisposable where TEntity : class
{
IUnitOfWork Session { get; }
IList<TEntity> GetAll();
IList<TEntity> GetAll(Expression<Func<TEntity, bool>> predicate);
bool Add(TEntity entity);
bool Delete(TEntity entity);
bool Update(TEntity entity);
bool IsValid(TEntity entity);
}
实现如下:
public class Repository : Component, IRepository
{
protected DbContext session;
public virtual IUnitOfWork Session
{
get
{
if (session == null)
throw new InvalidOperationException("A session IUnitOfWork do repositório não está instanciada.");
return (session as IUnitOfWork);
}
}
public virtual DbContext Context
{
get
{
return session;
}
}
public Repository(IUnitOfWork instance)
{
SetSession(instance);
}
public IList<TEntity> GetAll<TEntity>() where TEntity : class
{
return session.Set<TEntity>().ToList();
}
public IList<TEntity> GetAll<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
return session.Set<TEntity>().Where(predicate).ToList();
}
public bool Add<TEntity>(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Add(entity);
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public bool Delete<TEntity>(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Remove(entity);
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public bool Update<TEntity>(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Attach(entity);
session.Entry(entity).State = EntityState.Modified;
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public virtual bool IsValid<TEntity>(TEntity value) where TEntity : class
{
if (value == null)
throw new ArgumentNullException("A entidade não pode ser nula.");
return true;
}
public void SetSession(IUnitOfWork session)
{
SetUnitOfWork(session);
}
protected internal void SetUnitOfWork(IUnitOfWork session)
{
if (!(session is DbContext))
throw new ArgumentException("A instância IUnitOfWork deve um DbContext.");
SetDbContext(session as DbContext);
}
protected internal void SetDbContext(DbContext session)
{
if (session == null)
throw new ArgumentNullException("DbContext: instance");
if (!(session is IUnitOfWork))
throw new ArgumentException("A instância DbContext deve implementar a interface IUnitOfWork.");
this.session = session;
}
}