我见过很多在 MVC3 应用程序中使用实体框架的示例,它们都是非常简单的演示,只有一个包含 edmx 的 mvc3 Web 项目。
因此,他们可以通过“using”语句使用打开和关闭连接的最佳实践:
using(var context = new SchoolEntities())
{
// do some query and return View with result.
}
并且,它可以在“using”语句中正确使用延迟加载(导航属性),因为上下文还没有
处置:
foreach(var item in student.Course)
{
// do something with the navigation property Course
}
一切看起来都很完美,直到它成为一个 n 层应用程序。
我创建了 DAL、BLL 和 MVC3 UI。
The DAL里面有 edmx,以及像这样的操作符类SchoolDA.cs:
public class StudentDA()
{
public Student FindStudent(int studentId)
{
using(var context = new SchoolContext())
{
// do query, return a student object.
}
}
}
然后,在 BLL 中,如果我使用:
var student = studentDa.FindStudent(103);
然后调用它的导航属性:
student.Course
我会得到一个错误(当然):
ObjectContext 实例已被释放,不能再用于需要连接的操作。
所以,我必须像这样更改 StudentDA.cs:
public class StudentDA() : IDisposable
{
private SchoolEntites context;
public StudentDA()
{
context = new SchoolEntities();
}
public void Dispose()
{
context.Dispose();
}
public Student FindStudent(int studentId)
{
// do query, return a student object.
}
}
然后,BLL将发生如下变化:
public Student FindStudent(int id)
{
using(var studentDa = new StudentDA())
{
// this can access navigation properties without error, and close the connection correctly.
return studentDa.FindStudent(id);
}
}
一切似乎又变得完美了,直到遇到Update()方法。
现在,如果我想更新从 BLL.FindStudent() 获取的学生对象,context.SaveChanges() 将返回 0,因为上下文已在 BLL.FindStudent() 中释放,并且数据库中不会更新任何内容。
var optStudent = new StudentBO();
var student = optStudent.FindStudent(103);
student.Name = "NewValue";
optStudent.Update(student);
有谁知道如何在 3 轮胎应用程序中使用 EntityFramework?或者我如何正确管理上下文。我会经常在 Web 层中使用导航属性,但我不能始终保持连接打开以消耗服务器内存。