MVC 存储库体系结构和访问不同的表

本文关键字:访问 存储 体系结构 MVC | 更新日期: 2024-10-31 10:44:24

谢谢你帮助我理解其中的一些东西:

假设我在 MVC 应用程序中有 2 个控制器 -1 控件视图与销售人员相关的模型1 控件视图与销售相关的模型

每个都有自己的存储库,该存储库使用实体框架(代码优先)访问数据

这两个存储库都设置为处理依赖项注入,但也具有 0 个参数构造函数,其默认值为使用适当的 EF dataAccess。

SalesPeople

控制器使用 _salesPeopleRepository.getAllSalesPeople() 函数,该函数返回销售人员列表以填充索引视图。

销售总监需要访问同一列表以填充下拉列表。

有几种方法可以将信息传递给销售总监,我想知道哪些选项将被视为最佳实践:

a) 在控制器中

db = new DataContext();
_saleRepos = new SalesRepository(db);
_salesPeople = new SalesPeopleRepository(db);
 .....
modelA.SalePeopleSelectList = SelectList(_salesPeople.getAllSalesPeople(),"id","name")

b) 在销售存储库中 - 使用 EF 本身:

public IEnumerable<salesPerson> getAllSalesPeople()
{ 
    return _db.SalesPeople.ToList();
}

c) 或在调用函数之前实例化并注入相同的数据访问对象

public IEnumerable<salesPerson> getAllSalesPeople()
{ 
    return (new SalesPersonRepository(_db)).getAllSalesPeople();
}

编辑

如果答案是a),应该如何从1个存储库调用自定义业务逻辑 - 例如销售有一个storeId,存储库检查为销售输入的storeID是否与salesPerson的storeId匹配。用于业务逻辑目的的 salesPerson 对象(在 salesRepository 中)应该通过 salesPerson 存储库访问,还是直接从 dataContext 对象访问?

感谢您的想法和经验

MVC 存储库体系结构和访问不同的表

SalesRepositorySalesPerson表中检索数据是没有意义的。该数据访问逻辑应集中在SalesPeopleRepository中。在我看来,跨存储库复制该方法只会把水搅浑。

那么,为什么不在销售控制器中同时使用SalesRepositorySalesPeopleRepository呢?我只是实例化SalesPeopleRepository的实例并使用其中已经定义的方法。

此外,如果您的控制器使用依赖注入,则可以将存储库传递给构造函数:

public SalesController (ISalesRepository salesRepository, ISalesPeopleRepository salesPeopleRepository)
{
   this._salesRepository = salesRepository;
   this._salesPeopleRepository = salesPeopleRepository;
}

最佳做法始终取决于上下文,但存储库和工作单元模式的组合经常在 EF 之上使用。

用法:

using (var uow as new DataContext()) {
    var salesPeople = new SalesPeopleRepository(uow);
    // ...
    uow.Commit(); // If changes must be committed back to the database
}

实现:

public interface IUnitOfWork {
    public void Commit();
}
public class DataContext : IUnitOfWork {
    public void Commit() {
        this.SaveChanges();
    }
}
public class SalesPeopleRepository {
    private DataContext _db
    public SalesPeopleRepository(IUnitOfWork uow) {
        _db = uow as DataContext;
    }
    public IEnumerable<SalesPerson> GetAllSalesPeople() { 
        return _db.SalesPeople.ToList();
    }
}

首先,应遵循 C# 命名约定:getAllSalesPeople() 应为 GetAllSalesPeople。其次,在这种情况下,IoC 容器和依赖项注入将是最佳实践。

a项应该被宣布,因为DataContext和存储库是直接在控制器中创建的,它违反了依赖注入,并使你的代码与存储库和DataContext紧密耦合,并且无法模拟单元测试。相反,存储库应注入控制器,DataContext 应注入存储库。

public Repository(DataContext dataContext)
{
    _dataContext = dataContext;
}
public SalesController(ISalesRepository salesRepository, 
                          ISalesPeopleRepository salesPeopleRepository) 
{ 
   _salesRepository = salesRepository; 
   _salesPeopleRepository = salesPeopleRepository; 
} 

DataContext 的生存期管理应该保留在 IoC 容器中的每个请求中,而不是直接在控制器中创建,大多数 IoC 容器都支持这一点。不知道你使用哪个IoC容器,但我最喜欢的是:Autofac和Windsor。

对于项目 c,您正在使业务逻辑泄漏到存储库层,相反,业务逻辑应位于控制器或单独的层中。存储库只处理数据库的 CRUD 操作。