当前系统:
我正在开发一个多层次的项目,如下所示(按流程顺序),我正在学习并尝试首先在EF数据库上使用UOW实现Repo模式。
存储库:
通用存储库:
public interface IRepository<TEntity> where TEntity : class
{
void Create(TEntity entity);
IQueryable<TEntity> ReadAll();
TEntity ReadById();
IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate);
TEntity ReadSingle(Expression<Func<TEntity, bool>> predicate);
TEntity ReadSingleOrDefault(Expression<Func<TEntity, bool>> predicate);
void Delete(TEntity entity);
}
存储库实施:
internal class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
private bool _isDisposed;
private readonly DbSet<TEntity> _dbSet;
private Entities _entities;
public RepositoryBase(Entities entities)
{
this._entities = entities;
this._dbSet = _entities.Set<TEntity>();
}
public IQueryable<TEntity> ReadAll()
{
return _dbSet;
}
public TEntity ReadById()
{
// Dummy return. Don't worry about returning null will be implemented later.
return null;
}
public IQueryable<TEntity> Filter(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.Where(predicate);
}
public TEntity ReadSingle(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.Single(predicate);
}
public TEntity ReadSingleOrDefault(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.SingleOrDefault(predicate);
}
public void Create(TEntity entity)
{
_dbSet.Add(entity);
}
public void Delete(TEntity entity)
{
_dbSet.Remove(entity);
}
public virtual void Dispose(bool isManuallyDisposing)
{
if (!_isDisposed)
{
if (isManuallyDisposing)
_tatwaEntities.Dispose();
}
_isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~RepositoryBase()
{
Dispose(false);
}
Generic UOW:
public interface IUnitOfWork
{
IRepository<MyEntity> MyEntityRepository { get; }
//Other EntityRepositories
void SaveChanges();
}
UOW实施:
public class UnitOfWork : IUnitOfWork, IDisposable
{
private Entities _entities;
public UnitOfWork()
{
_entities = new entities();
}
private IRepository<MyEntity> _myEntityRepository;
public IRepository<MyEntity> MyEntityRepository
{
get
{
return _myEntityRepository ?? (_myEntityRepository = new RepositoryBase<MyEntity>(_entities));
}
}
public void SaveChanges()
{
_entities.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_entities != null)
{
_entities.Dispose();
_entities = null;
}
}
}
}
业务逻辑
public List<MyViewModel> ReadMyViewModelList()
{
var myVMList = new List<MyViewModel>();
using (var unitOfWork = new UnitOfWork())
{
userList.AddRange(unitOfWork.MyEntityRepository.ReadAll().Select(myEntity => new myViewModel
{
Prop1 = myEntity.Prop1,
Prop1 = myEntity.Prop2,
etc...
}));
}
return myVMList;
}
问题:
希望我的问题很精细。由于我处于建立架构的学习阶段,我感谢任何其他建议/意见/改进。
干杯。
答案 0 :(得分:3)
这是我如何设计我的存储库,希望它有所帮助。合同如下:
public interface IFooRepository
{
void Add(Foo foo);
IReadonlyList<Foo> GetAll();
IReadonlyList<Foo> GetAParticularSubset();
Foo GetById(int id);
Foo Remove(int id);
}
注意集合语义。存储库的设计就好像它是可以添加,删除或查询的域对象的内存列表。 存储库的主要作用是充当我们假装数据库永远不存在的抽象。所以没有Update()
,没有Commit()
等。方法返回简单的只读对象列表,没有IQueryable
,因为它是来自较低持久层的leaky abstraction,具有不需要的功能,如高级查询操作。
在内部,具体的EF存储库有DbContext
。他们使用它来添加/删除内容和查询,但不保存更改(见下文)。
工作单位有一个愚蠢的简单签名:
公共接口IUnitOfWork { void SaveChanges(); }
这是“我提交我的业务交易,请将其刷新到所有必须存储的内容”,这是存储库中遗漏的部分。我们基本上不希望它在回购中因为分离关注。为人们提供一堆对象并提供跟踪这些对象与持久性存储相关的变化的上下文是两个截然不同的事情。
事实证明,实体框架可以并且将会为您完成这两项工作。这两个功能都体现在DbContext
中。但是,虽然Repository将调用DbContext.Foos.Add/Remove
/查询方法,但UnitOfWork只会调用DbContext.SaveChanges()
。
因此,Repository
和UnitOfWork
都需要引用DbContext
。如果要使对象中的更改生效,它必须是DbContext的相同实例。这可以通过DI容器注入相同的实例来完成(假设你正在使用它)。
从消费者的角度来看,当您打算更改对象时,您只需将自己置于UnitOfWork
范围内。对于不会修改结果的简单查询,只需使用Repo。