asp.net-mvc - 每种实现的存储库模式优缺点

标签 asp.net-mvc repository-pattern

嗨,看看通常似乎实现如下的存储库模式:

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;
    }
}

因此,对于您想要使用的每种类型(即更新),您需要实例化一个存储库。

因此,如果我有两种类型,我想保存 CarsTrucks我需要去:
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/

相关文章:

entity-framework - 将存储库模式与 EF 4.1 数据库优先方法结合使用

c# - 如何设置ID对应 Entity Framework 中的对象

asp.net - .NET 中的 Web 开发 - 使用哪些技术来构建和使用您自己的 API?

asp.net-mvc - DbContext 错误?检索新保存的记录后导航属性为空

c# - Entity Framework 存储库模式继承

c#-4.0 - 使用 Moq 模拟存储库时出现问题

domain-driven-design - 存储库添加和创建方法

asp.net-mvc - MVC 3 - 在 View 中显示字典中的值

c# - ASP.NET MVC F# Controller 操作忽略参数

c# - 使用webclient上传文件时如何指定form参数