使用using声明Entity Framework上下文

10

如何声明Entity Framework上下文的最佳实践

function()
{
    DBContext context = new DBContext();

    //Entity code

    return ;
}
或者
function()
{
    using(DBContext context = new DBContext())
    {
        //Entity code
    }
}

我们需要在 EntityFrameWork 中使用 using 吗?如果是,那么我的第二个问题是:

在数据访问层中,我正在使用 EF 并将结果存储在 using 内部的 IEnumerable 中。

我的数据访问层

function()
{
    IEnumerable something = null;
    using(DBContext context = new DBContext())
    {
        IEnumerable something = ....
    }
    return something;
}

在控制器中

function()
{
    List some = something.ToList();
}

在我的控制器中,我将其作为列表获取,因为我需要进行一些查找操作

"The operation cannot be completed because the DbContext has been disposed Entity Framework"

是的,我可以从DL返回一个列表,并且它运行良好。

如果我使用IEnumerable,我该如何处理它?


1
我认为这个SO链接正是你所问的:https://dev59.com/rnRA5IYBdhLWcg3wyRJ7?rq=1 - Conrad Clark
是的,请检查我的第二个问题。 - user2067567
可能是Using Statement and Entity Framework的重复问题。 - Habib
3个回答

8

在上下文被销毁之前(即在您的using块内),调用IEnumerable上的.ToList()可以避免EF懒加载行为。


是的,仍然像Paul所说的那样使用using。给你加1。但是如果您的模型具有孙对象,则仍会遇到类似的问题。我还没有花时间解决这个问题。 - Lotok
1
@James 我认为您可以在原始的 Linq 语句中使用 .Include() 来获取您的子孙节点。 - paul
问题在于,对于大型数据集,这将把整个数据集加载到内存中,而使用游标和IEnumerable时,您首先要避免这种情况。 - Gudlaugur Egilsson

7

是的,使用using是最佳实践,因为它可以清理上下文。 Using语句 是以下代码的快捷方式:

try {
    // Execute your code inside the using statement
}
finally {
    // Cleanup the context no matter what by calling .Dispose()
}

请记住,您的上下文可能返回IEnumerables,由于EF支持延迟加载,这些对象在您将它们获取到具体集合(例如yourResult.ToList())之前不会被填充。

在这种情况下,常见的负面结果如下:

public IEnumerable<Employee> GetEmployeesInAccounting()
{
    using(var myContext = new MyDbContext())
    {
        return myContext.Employees.Where(emp => emp.Department == 'Accounting');
    }
}

// Code that fails, Assuming Manager is a lazy loaded entity, this results in an exception but it compiles no problem
var acctEmps = GetEmployeesInAccounting();
var something = acctEmps.First().Department.Manager.Department;

您可以通过使用.Include(emp => emp.Manager)(linq扩展方法)来避免这种情况,并使用.ToList();绑定您的结果。

3

只有在调用 .ToList() 方法时,您的请求才会立即向数据源执行。

这就是为什么您不能在控制器中执行 .ToList(),因为您的上下文已在 using 块结束时被释放。

在您的 DL 方法中,只需执行以下操作:

IEnumerable<Something> function()
{
    using(DBContext context = new DBContext())
    {
      return something.ToList();
    }
}

在您的控制器中,您将获得一个Something的IEnumerable:
var mySomethingIEnumerable = DL.Function();

希望这能帮到您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接