【问题标题】:MVC EF Context InstancesMVC EF 上下文实例
【发布时间】:2014-02-03 10:09:40
【问题描述】:

如果我的问题看起来很愚蠢,我深表歉意,我尝试了谷歌搜索,但没有找到我要找的东西,所以任何建议都将不胜感激。

我对 MVC 的想法还很陌生,我从事 Web 表单开发已经很多年了,但我想尝试一下其他的东西。

我将实体框架 (6) 用于数据库连接,并将 MVC4 用于 Web 前端。

我的问题是,数据库上下文实例应该如何处理。

我的控制器动作代码是这样的

public ViewResult List(int buildingId)
{
    var model = new Data.Model();
    var query = from r in model.Rooms
                where r.Building.Id == buildingId
                select r;
    /*
    var q2 = model.Buildings.Where(b => b.Id == buildingId).SelectMany(b => b.Rooms);
    var q3 = model.Buildings.Where(b => b.Id == buildingId).First().Rooms;
    */

    return View(query);
}

注释行只是我可以获得我正在寻找的查询结果的其他方式。 Data.Model 是 EF Db 上下文。

我不喜欢这里的上下文是一次性的,我不会处理它。在我看来,这是一种懒惰和不好的做法。

我已经使用model begin 处理进行了测试,我需要的第一个更改是返回查询列表,我不介意,但是由于上下文已处理,在视图上我无法访问属性喜欢@item.Building.Description。因此,如果要进行处理,我需要准确返回要在视图上显示的内容(我可以通过多种方式做到这一点,所以我不太担心如何)。

另一种选择是在项目中的某处使用静态/共享上下文,因此所有数据库请求都使用相同的上下文实例。这很好,因为它只会使用一个 DB 连接,但 EF 可能已经为我处理了这个问题,所以我不想反对使用 EF 的设计方式,如果它应该是这样的话.

那么,我的问题是,什么是最佳实践?

  • 继续像我一样工作,实例化一个新的上下文,而不是处置。
  • 每次都处理上下文,并确保我返回任何我需要在视图上可见的内容。
  • 如果已实例化,则使用将返回静态上下文实例的类。

谢谢

【问题讨论】:

    标签: .net asp.net-mvc entity-framework asp.net-mvc-4


    【解决方案1】:

    一般来说,我会建议使用更结构化的方法,并使用单独的(提供数据的)层从数据库中获取数据。在这种情况下,IoC(控制反转)容器(例如 Ninject、Unity 等)可以为您处理对象生命周期,但如果您之前没有使用过依赖注入模式,那么您首先需要研究很多。

    话虽如此,简单的答案是您绝对应该尽快处置您的context 对象(通常它们应该尽可能短)。常见的模式是

    using (var model = new Data.Model())
    {
        var buildings = model.Rooms.Where(r => r.Building.Id == buildingId).ToList();
    }
    

    您可以通过调用ToList() 立即获取数据并处理上下文。这避免了您在返回查询并将其传递给视图时遇到的问题。正如您所注意到的,控制您的 DB 查询何时被执行以及何时处置上下文变得非常棘手。

    Another option would be to have a static/shared context somewhere in the project, so all database requests use the same context instance - 这是一个可怕的想法,也是众所周知的不良做法/反模式。

    总而言之,最佳做法是按照您在列表中选项 2 中的描述工作:Dispose the context each time, and make sure I return anything I need visible on the view.

    作为旁注,对每个视图使用一个 ViewModel 也是一种好习惯(请参阅ASP.NET MVC - How exactly to use View Models

    【讨论】:

    • 你好 Yakimych。在这个例子中,我实际上是在寻找建筑物中的房间列表,但这并不会改变给出的答案。
    • @JonathanPeel - 是的,对不起,你当然是对的。我已经从答案中删除了FirstOrDefault 评论。
    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    相关资源
    最近更新 更多