UnitOfWork通常提供这种抽象。这是一个需要更改的地方,您的存储库通过接口依赖它。如果您需要更改O / RM,只需对其实施新的UoW。一劳永逸。
顺便说一句,它不仅仅是切换O / RM,还可以考虑单元测试。我有三种UnitOfWork实施,一种用于EF,一种用于NH(因为我实际上DID必须为需要Oracle支持的客户端切换项目中的O / RM),以及一种用于InMemory持久性。InMemory持久性非常适合在我准备将数据库置于其后的单元测试或快速原型制作中。
该框架易于实现。首先,您具有通用的IRepository接口
public interface IRepository<T>
where T:class
{
IQueryable<T> FindBy(Expression<Func<T,Bool>>filter);
IQueryable<T> GetAll();
T FindSingle(Expression<Func<T,Bool>> filter);
void Add(T item);
void Remove(T item);
}
和IUnitOfWork接口
public interface IUnitOfWork
{
IQueryable<T> GetSet<T>();
void Save();
void Add<T>(T item) where T:class;
void Remove<T>(T item) where T:class;
}
接下来是基础存储库(您是否应该选择抽象存储库的选择
public abstract class RepositoryBase<T>:IRepository<T>
where T:class
{
protected readonly IUnitOfWork _uow;
protected RepositoryBase(IUnitOfWork uow)
{
_uow=uow;
}
public IQueryable<T> FindBy(Expression<Func<T,Bool>>filter)
{
return _uow.GetSet<T>().Where(filter);
}
public IQueryable<T> GetAll()
{
return _uow.GetSet<T>();
}
public T FindSingle(Expression<Func<T,Bool>> filter)
{
return _uow.GetSet<T>().SingleOrDefault(filter);
}
public void Add(T item)
{
return _uow.Add(item);
}
public void Remove(T item)
{
return _uow.Remove(item);
}
}
实施IUnitOfWork是EF,NH和In Memory的小事。我返回IQueryable的原因是相同的,Ayende在他的帖子中提到,客户端可以使用LINQ进一步过滤,排序,分组甚至投影结果,您仍然可以从服务器端受益。