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

本文关键字:DbContext NET 于使用 EF ASP | 更新日期: 2023-09-27 18:31:52

自从我一直在使用MVC框架开发Web应用程序以来,我一直想知道我应该在哪里定义DbContext。我知道内存泄漏,通常,也就是ConsoleApplication,我会在using() {}子句中附上DbContext的使用。但是,Web 应用程序似乎有所不同,我很确定DbContext的生命周期是不同的,我不能只是将其处理为控制器,然后尝试在视图中读取它。或者也许我在这里错了。起初,我在每个操作中创建多个引用。我的想法是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);
}

当我在行中引用视图中的@Model时,抛出异常说:"操作无法完成,因为 DbContext 已被释放":

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

请注意,代码以其他方式工作,除了删除using() {}之外没有任何其他更改。

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

没有什么不同。调用视图时,控制器已失效。在控制器中的操作中使用 use,因此不要保留 DbContext。

通常:在处理和 EF 上下文方面,MVC 与任何其他 .NET 技术没有什么不同。

尝试选择

新的 {...} 中的 ToList。到列表()您正在尝试从可查询的源访问数据。该源在使用范围的末尾关闭。

由于viewModel是一个IQueryable<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>