gpt4 book ai didi

entity-framework - 如何使用 Entity Framework 在多层应用程序中正确管理 ObjectContext 生命周期?

转载 作者:行者123 更新时间:2023-12-04 07:26:53 25 4
gpt4 key购买 nike

我看过很多在 MVC3 应用程序中使用 Entity Framework 的例子,它们都是非常简单的演示,只有一个 mvc3 web 项目,里面有 edmx。

因此,他们可以通过“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。

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 层中经常使用导航属性,但我不能始终保持连接打开以消耗服务器内存。

最佳答案

有多种方法可以处理 EF 上下文的生命周期。在 Web 应用程序中,上下文对于 HttpRequest 通常是唯一的。例如,如果您想在 Web 应用程序中手动处理此问题并拥有每个 Thread/HttpRequest EF 上下文,您可以使用以下代码(从 http://www.west-wind.com/weblog/posts/2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management 复制的代码):

internal static class DbContextManager
{
public static DbContext Current
{
get
{
var key = "MyDb_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as MyDbContext;

if (context == null)
{
context = new MyDbContext();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}

然后你可以很容易地使用:

var ctx = DbContextManager.Current

但我建议您将生命周期管理留给 IoC 框架,例如 Autofac , Castle Windsor , 或 Ninject它会自动处理您注册对象的创建/处置以及许多其他功能。

关于entity-framework - 如何使用 Entity Framework 在多层应用程序中正确管理 ObjectContext 生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11945715/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com