嗨,看看通常似乎实现如下的存储库模式:
public class GenericRepository<TEntity> where TEntity : class
{
// other business
public virtual TEntity GetByID(object id)
{
return db.Set().Find(id);
}
public virtual void Insert(TEntity entity)
{
db.Set().Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = db.Set().Find(id);
Delete(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
db.Set().Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
因此,对于您想要使用的每种类型(即更新),您需要实例化一个存储库。
因此,如果我有两种类型,我想保存
Cars
和 Trucks
我需要去:var carRepository = new GernericRepository<Car>();
carRepository.Update(myCar);
var truckRepository = new GernericRepository<Truck>();
carRepository.Update(myTruck);
因此,您对每种类型都有单独的存储库。为确保您一次保存所有内容,您需要
unitOfWork
以确保它们都使用相同的上下文并一次保存。拥有类似的东西肯定不是更好:
public class GenericRepository
{
// other business
public virtual TEntity GetByID<TEntity>(object id) where TEntity : class
{
return db.Set<TEntity>().Find(id);
}
public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
{
db.Set<TEntity>().Add(entity);
}
public virtual void Delete<TEntity>(object id) where TEntity : class
{
TEntity entityToDelete = db.Set<TEntity>().Find(id);
Delete(entityToDelete);
}
public virtual void Update<TEntity>(TEntity entityToUpdate) where TEntity : class
{
db.Set<TEntity>().Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
这意味着存储库只需要实例化一次,因此真的是通用的吗?
所以你可以像这样更新你的汽车和卡车:
var repository = new GernericRepository<Car>();
repository.Update<Car>(myCar);
rRepository.Update<Truck>(myTruck);
当然这是一个更好的方法?我错过了什么吗?它也自动只有一个上下文。
最佳答案
存储库模式不会将数据访问与数据存储分离,这正是 NHibernate 或 Enity Framework 等 ETL 工具所做的。存储库模式为提取数据提供了可重用的方法。
正如您所描述的,我以前使用过一个所谓的“通用”存储库,并认为它很棒。直到您意识到您刚刚在 NHibernate 或 Entity Framework 之上添加了另一层,您才意识到这一切都消失了 Pete Tong。
理想情况下,您需要的是描述从数据存储中获取数据的方式的接口(interface),并且不应该泄露您正在使用的数据访问权限。例如:
public interface IEmployee
{
IEmployee GetEmployeeById(Guid employeeId);
IEmployee GetEmployeeByEmployeeNumber(string employeeNumber);
IEnumerable<IEmployee> GetAllEmployeesWithSurname(string surname);
IEnumerable<IEmployee> GetAllEmployeesWithStartDateBetween(DateTime beginDateTime, DateTime endDateTime);
}
这为您提供了一个代码契约,不了解您的持久层,并且用于检索数据的查询可以单独进行单元测试。该接口(interface)可以从提供通用 CRUD 方法的基本接口(interface)继承,但您会假设您的所有存储库都需要 CRUD。如果您走通用存储库的道路,您最终会在查询中出现重复,并且您会发现对使用存储库的代码进行单元测试要困难得多,因为您还必须测试查询。
关于asp.net-mvc - 每种实现的存储库模式优缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6852595/