在哪里为 DbContext 添加实用方法?

Where to add utility methods for DbContext?

所以我有一个 ASP.NET MVC 5 应用程序 ASP.NET Identity 2.0 运行。一切都很好,但我想重构我的代码,我想知道我当前的实现有哪些替代方案。让我解释一下。

我在项目的根目录中有控制器,在项目的区域文件夹中也有很多控制器。几乎所有这些都继承自 BaseController class,后者又继承自 System.Web.Mvc.Controller。这个 BaseController 看起来像这样:

public class BaseController()
{
    protected ApplicationUserManager _userManager;
    protected ApplicationRoleManager _roleManager;
    protected readonly MyDbContext _db = new MyDbContext();

    public BaseController()
    {
    }

    public BaseController(ApplicationUserManager um, ApplicationRoleManager rm)
    {
        UserManager = um;
        RoleManager = rm;
    }

    public ApplicationUserManager UserManager { ... }
    public ApplicationRoleManager RoleManager { ... }

    #region Utility Methods

    // Here are over 60 utility methods that are basically queries on _db

    #endregion
}

更多方法正在开发中,我不禁觉得有比将它们放在基础中更好的方法 class 从逻辑上讲,并非每个控制器都应该直接继承这些方法。

将它们移动到 MyDbContext(继承 IdentityDbContext)实际上只是将它们移动到 更适用的 文件。我想象的是 MyDbContext 中的每个 DbSet 都有自定义实用程序方法,但我不确定该怎么做。像下面这样的东西是理想的:

Semester thisSemester = _db.Semesters.GetCurrentSemester();

SelectList semesters = _db.Semesters.GetAllSemestersAsSelectList();

其中 Semesters 在两个示例中都是 DbSet<Semester> 类型。

谁能提供解决方案?

当我看到类似...的方法时

_db.Semesters.GetAllSemestersAsSelectList()

...我认为这将是一种扩展方法(除非您有自己的 DbSet 实现)。但是扩展方法是为真正通用的任务设计的,而不是为这样的特定任务设计的。此外,它要求在任何你想要这个 select 列表的地方你都可以访问 DbSet

最好在服务中执行此操作 class 这样您就可以调用类似

的方法
_semesterService.GetAllSemestersAsSelectList()

这项服务可能看起来像

class SemesterService : ISemesterService
{
    private readonly MyDbContext _context;

    /// <summary>
    /// Constructor in which an IoC container can inject a context.
    /// </summary>
    /// <param name="context"></param>
    public SemesterService(MyDbContext context)
    {
        this._context = context;
    }

    public SelectList GetAllSemestersAsSelectList()
    {
        return new SelectList(_context.Semesters, "Id", "Name");
    }

    public Semester GetCurrentSemester()
    {
         return _context.Semesters.Where(....).FirstOrDefault();
    }
}

举个例子。

可能从服务 return 学期开始并在 MVC 控制器中构建 SelectList 更好,这样服务层就不会依赖 MVC。