【问题标题】:What design pattern is preferable when working with ASP.Net MVC and Entity Framework?使用 ASP.Net MVC 和实体框架时,哪种设计模式更可取?
【发布时间】:2009-10-26 18:16:57
【问题描述】:

我不太确定在使用 ASP.Net MVC 和实体框架时使用哪种设计模式最有效,因此非常感谢任何指导!

您是将上下文存储在 Controller 类中,还是创建存储库更好?

如果您推荐 repo 设计,是否需要在每个方法中初始化上下文,像这样?或者这是一种更好的方法?:

public SomeEntity GetEntity(Guid id) {
   using(Context ctx = new Context()) {
      // code here...
   }
}

【问题讨论】:

    标签: asp.net-mvc design-patterns entity-framework


    【解决方案1】:

    我使用存储库模式。上下文在存储库中,并且与存储库一样长。 Repository 在 Controller.Initialize 中初始化并在 Controller.Dispose 中处置。这意味着一个请求会在请求完成之前获得一个存储库/上下文,这非常有效——请求很短,因此可以快速处理上下文。但是当一个操作调用多个存储库方法时,它们都使用相同的上下文,这使得很多事情变得更容易。

    【讨论】:

    • 好的,谢谢。但是 Initialize() 方法和 Dispose() 方法在存储库中的外观如何?
    • 它们是控制器的方法,而不是存储库。您覆盖它们,调用 base,然后分配/处置您的存储库。在存储库的构造函数中,新建一个 ObjectContext。在 Dispose 中,释放上下文。
    • 如果我将存储库设置为控制器中的类变量(并显式初始化),是否不会自动分配/释放存储库?
    • 克雷格,我看了关于 EF 的在线演示,很棒。您是否有任何示例代码可供我下载以进一步了解您如何进行 CRUD。
    • 还没有,但我很快就会有东西。看我的博客。
    【解决方案2】:

    存储库模式是要走的路

    取决于您的项目大小,但如果它不是微不足道的,我会推荐存储库模式,因为它也更容易维护。

    尽可能晚打开上下文并尽快关闭
    与连接类似,您还应该尽快释放上下文,因此在通过 EF 实际读取/提交到 DB 之前进行任何其他处理。所以。使您的 using 块尽可能短。

    【讨论】:

    • 所以您说,正如 Craig 所建议的那样,在整个请求期间保持上下文处于活动状态不是最佳做法?
    • 没有。我只是说你应该尽可能晚地一起做存储库的东西。不要在上下文生命周期内进行任何不必要的处理。如果您需要做多个存储库的东西并且它们都与相同的上下文相关,那么当然可以一起做。如果需要,您还可以为多个呼叫重用相同的数据库连接,不是吗?思考/行动在这里是相似的。
    【解决方案3】:

    我用接口创建了自己的通用存储库类:

    public interface IRepository<T>
    {
        //Retrieves list of items in table
        IQueryable<T> List();
        IQueryable<T> List(params string[] includes);
        //Creates from detached item
        T Create(T item);
        //Updates from detached item
        //Attached item can be change directly and using SaveChanges
        T Edit(T item);
        void Delete(int id);
        void DeleteObject(object item);
        T Get(int id);
        T Get(int id, params string[] includes);
        void SaveChanges();
    }
    

    它负责基本的 CRUD 操作,它也有上下文。在存储库上,我有保存业务登录的服务类。示例:

    public interface IProjectService
    {
        IQueryable<Project> ListProjects();
        Project GetProjectByName(string name);
        Project GetProjectByID(int id);
        bool EditBasicProjectData(Project project);
        bool CreateProject(Project project);
        bool DeleteProject(int id);
        void SetCurrentProjectByID(int id);
    }
    

    每个服务都有必要的存储库。控制器具有由 NInject 注入的服务。控制器方法很短,它们只是将数据从服务传递到视图(以两种方式)。这使得整个项目易于测试。您可以模拟存储库来测试服务。您可以模拟服务来测试控制器。

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 1970-01-01
      • 2010-09-25
      • 2013-09-22
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多