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 对象访问?
感谢您的想法和经验
SalesRepository
从SalesPerson
表中检索数据是没有意义的。该数据访问逻辑应集中在SalesPeopleRepository
中。在我看来,跨存储库复制该方法只会把水搅浑。
那么,为什么不在销售控制器中同时使用SalesRepository
和SalesPeopleRepository
呢?我只是实例化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 操作。