【问题标题】:Where to add utility methods for DbContext?在哪里为 DbContext 添加实用方法?
【发布时间】:2015-07-30 22:05:43
【问题描述】:

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

我的项目根目录中有控制器,项目的区域文件夹中也有许多控制器。几乎所有这些都继承自 BaseController 类,而后者又继承自 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
}

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

将它们移至MyDbContext(继承IdentityDbContext)实际上只是将它们移至更适用的文件。我想象的是在MyDbContext 中为每个 DbSet 提供自定义实用程序方法,但我不知道该怎么做。理想的情况如下:

Semester thisSemester = _db.Semesters.GetCurrentSemester();

SelectList semesters = _db.Semesters.GetAllSemestersAsSelectList();

在这两个示例中,Semesters 的类型均为 DbSet<Semester>

谁能提供解决方案?

【问题讨论】:

    标签: asp.net-mvc entity-framework entity-framework-6 asp.net-identity asp.net-identity-2


    【解决方案1】:

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

    _db.Semesters.GetAllSemestersAsSelectList()
    

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

    最好在服务类中这样做,这样你就可以调用类似的方法

    _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();
        }
    }
    

    只是给你一个例子。

    也许最好只从服务中返回学期并在 MVC 控制器中构建 SelectList,这样服务层就不会依赖于 MVC。

    【讨论】:

    • 嘿,Gert,您能在其中介绍一下如何使用此实现来重组解决方案项目(现在我只有一个)吗?另外,我是否仍会为每个控制器创建数据库上下文,还是每个控制器都会初始化它需要的服务?
    • 我认为一个完善的解决方案结构取决于太多(对我而言)未知的细节,因此无法在此提出。至于初始化:没有依赖注入,在我看来,控制器将初始化一个服务和一个服务它的上下文。使用 IoC,IoC 容器将服务注入到控制器中(如果您要覆盖 MVC 控制器工厂),它会在其中注入上下文,所有这些都是通过构造函数注入来实现的。
    猜你喜欢
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多