使用EF 6.1.1在ASP.NET中使用DbContext

时间:2014-11-24 09:42:05

标签: c# asp.net asp.net-mvc entity-framework dbcontext

由于我一直在使用MVC框架处理我的Web应用程序,所以我一直在想我应该在哪里定义DbContext。我知道内存泄漏,通常在ConsoleApplication中,我会附上DbContext with using() {}子句的用法。但是,Web应用程序似乎有所不同,我很确定DbContext的生命周期是不同的,我不能只将它作为控制器处理,然后尝试在Views中读取它。或许我错了。起初,我在每个Action中创建了多个引用。我想到了这个想法,将DbContext定义作为每个控制器中的readonly private字段:

public HomeController : controller
{
    private readonly MyDBContext myDbContext = new MyDBContext();

    // ... and in actions

    public ActionResult Index()
    {
        // ... usage of myDbContext
    }

    public ActionResult Create()
    {
        // ... usage of myDbContext
    }

    public ActionResult Edit()
    {
        // ... usage of myDbContext
    }

    public ActionResult Delete()
    {
        // ... usage of myDbContext
    }
}

你认为这是对的。

干杯!

<小时/> 编辑: 我将代码更改为:

public ActionResult Index()
{
    IQueryable<MyViewModel> viewModel = null;
    using (MyDBContext dB = new MyDBContext())
    {
        viewModel = from st in dB.Students
                    join d in dB.Departments on st.DepartmentID equals d.DepartmentID
                    join g in dB.Genders on st.GenderID equals g.GenderID
                    select new MyViewModel
                    {
                        StudentID= st.StudentID,
                        StudentName = st.StudentName,
                        Gender = g.GenderName,
                        DepartName = d.DepartmentName
                    };
    }
    return View(viewModel);
}

并抛出异常说:“ 操作无法完成,因为DbContext已被处理 ”当我在行中查看@Model时:

@foreach (MyViewModel item in @Model) // compiler points at @Model

请注意,除了using() {}

之外,代码无效,没有任何其他更改

3 个答案:

答案 0 :(得分:1)

没有什么不同。调用视图时,Controller已死。在控制器中的操作中使用,所以不要保留DbContext。

通常:在处理和EF上下文方面,MVC中的NOTHING与任何其他.NET技术不同。

答案 1 :(得分:0)

尝试选择新的{...}中的ToList。ToList() 您正尝试从可共享的源访问数据。该源在使用范围结束时关闭。

答案 2 :(得分:0)

由于viewModelIQueryable<MyViewModel>,因此它不会保存控制器中的数据。它包含查询的执行计划,该计划将在您的视图中执行时执行

@foreach (MyViewModel item in @Model)

您收到错误是因为上述语法在using块之外,因此DbContext已经处理掉,并且此时无法执行查询。虽然删除using块会使代码正常运行,但这并不是MVC的最佳实践。该模型应该只保存数据,视图根本不应该进行任何数据库操作。

正确的方法是使用IEnumerable<MyViewModel>代替IQueryable<MyViewModel>作为模型,因此viewModel将保留using块之后的数据。您可以使用ToList()方法强制执行using块内的查询,如下所示

public ActionResult Index()
{
    IEnumerable<MyViewModel> viewModel = null;
    using (MyDBContext dB = new MyDBContext())
    {
        viewModel = (from st in dB.Students
                    join d in dB.Departments on st.DepartmentID equals d.DepartmentID
                    join g in dB.Genders on st.GenderID equals g.GenderID
                    select new MyViewModel
                    {
                        StudentID= st.StudentID,
                        StudentName = st.StudentName,
                        Gender = g.GenderName,
                        DepartName = d.DepartmentName
                    }).ToList();
    }
    return View(viewModel);
}

并确保您在视图代码顶部使用以下语法

@model IEnumerable<MyViewModel>