MVC EF上下文实例

Jon*_*eel 2 .net asp.net-mvc entity-framework asp.net-mvc-4

如果我的问题看起来很愚蠢,我很抱歉,我已经尝试了谷歌搜索,而没有找到我要找的东西,所以任何建议都会受到赞赏.

我对MVC的想法相当新,我已经做了很多年的Web Forms开发,但是我想尝试别的东西.

我使用Entity Framework(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);
}
Run Code Online (Sandbox Code Playgroud)

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

我不喜欢这个是上下文是一次性的,我没有处理它.在我看来,这是懒惰和不好的做法.

我已经测试了model开始处理,我需要的第一个更改是返回查询列表,我不介意,但是因为上下文被处理,在视图上我无法访问属性,如@item.Building.Description.因此,如果处理我需要准确地返回我在视图上显示的内容(我有多种方法可以做到这一点,所以我不是很担心如何).

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

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

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

谢谢

Yak*_*ych 5

通常,我建议使用更具体系结构的方法,并使用单独的(数据提供)层从数据库中获取数据.在这种情况下,IoC(控制反转)容器(如Ninject,Unity等)可以为您处理对象生命周期,但如果您之前没有使用过依赖注入模式,那么您需要先进行大量调查.

话虽如此,简单的答案是你应该context尽快处理你的物品(通常它们应该尽可能地短暂).而常见的模式是

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

您可以通过调用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.

作为旁注,每个View使用ViewModel也是一个很好的做法(参见ASP.NET MVC - 如何使用View Models)