关于使用 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() {}
之外没有任何其他更改。
没有什么不同。调用视图时,控制器已失效。在控制器中的操作中使用 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>