【问题标题】:MVC Repository pattern where data will be loaded from multiple table从多个表加载数据的 MVC 存储库模式
【发布时间】:2017-12-05 10:02:15
【问题描述】:

我正在使用带有 EF6 的 MVC 5 来开发应用程序。我正在遵循存储库设计模式。像往常一样,有一个 Generic Repository 层,它有一个类型参数 GenericRepository。存储库包含 GetAll 函数:

    public virtual List<T> GetAll()
    {
        IQueryable<T> query = _entities.Set<T>();
        return query.ToList();
    }

此存储库已从服务层调用。在服务层还有一个叫做GetAll()的函数。函数如下:

    public List<Student> GetAll()
    {
        return _unitOfWork.StudentRepository.GetAll();
    }

存储库一次处理单个实体。在此示例中,我仅从 Student 表中检索数据。我的问题是,如果我想从多个表中检索数据,比如 Student Department 和 Country 并将其显示在视图中,这怎么可能?我的控制器代码是这样的:

        public ActionResult Index()
        {
            return View(student.GetAll());
        }

我应该如何以及在何处包含“位置”和“州”实体。我也有一个 UnitOfWork 层。图层是这样的:

public class UnitOfWork : IUnitOfWork
    {
        private readonly ConnString _context;
        private IGenericRepository<Student> studentRepository;
        private IGenericRepository<Department> departmentRepository;
        private IGenericRepository<Country> countryRepository;

        public UnitOfWork()
        {
            this._context = new ConnString();
        }

        public IGenericRepository<Student> StudentRepository
        {
            get { return this.studentRepository ?? (this.studentRepository = new GenericRepository<Student>(_context)); }
        }

另一个问题是,如果我想在视图中生成下拉列表(例如,部门和国家),我该怎么做?

任何帮助都将被接受。

谢谢 帕萨

【问题讨论】:

  • 如果我理解正确,理想情况下,您的服务层或您的控制器可以协调从多个存储库获取数据,将它们组合到单个实体中(如果您的存储库方法返回 IQueryable&lt;T&gt; 而不是集合或通过基于父数据有条件地查询每个存储库)并将其传回。
  • 在服务层中,我将“”实体作为 GetAll() 函数中的列表返回。学生是单一实体。我需要像 这样的东西。这种模式怎么可能?
  • 我相信您刚刚发现了为什么 EF 使用具有多种实体类型的单个存储库:DbContext。

标签: entity-framework model-view-controller repository-pattern


【解决方案1】:

首先。存储库模式不包装表。它包装域实体。它们可能存储在一个表中,也可能不存储。

对于您的场景,控制器的工作是从模型(业务层)获取信息并使其适应视图的要求。

因此我会这样做:

var students = _studentRepos.GetStudentsInSchool(schoolId);
var departmentIds = students.Select(x=>x.DepartmentId).Distinct();
var departments = _departmentRepos.GetAll(departmentIdS);
var countryIds = studens.Select(x=>x.CountryId).Distinct();
var countries = _countryRepos.GetAll(countryIds);

var items = new List<StudentSummaryModel>();
foreach (var student in studens)
{
    var item = new StudentSummaryModel(student);
    item.CountryName = countries.First(x=>x.Id == student.CountryId).Name;
    item.DepartmentName = departments.First(x=>x.Id == student.DepartmentId).Name;
    items.Add(item)
}

return View(items);

代码合理易读,不同业务领域分开。

【讨论】:

  • 如果要添加数据,则可能需要事务,以确保仅在将学生添加到现有部门时才添加两个条目,或者仅在缺少新部门时才添加新部门,并且只有当学生也被添加时。虽然在简单的 MVC 模式中控制器负责,但事务在任何情况下都不应该是控制器的一部分。这个答案提出了一项服务,可以合理地实施交易:stackoverflow.com/questions/41297655/…
  • 另一个方面是保持控制器尽可能纤薄。有太多的逻辑让人难以阅读,并且不专注于处理请求,而是专注于在特定类中更好地外包的细节。
  • 所有要点都有效,大卫,但您的答案超出了问题范围。
猜你喜欢
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多