EF(实体框架)使用“使用”语句

时间:2013-07-30 10:42:13

标签: c# entity-framework garbage-collection dbcontext using-statement

我有一个关于MVC的项目。我们为数据库交易选择了EF。我们为BLL层创建了一些管理器。我找到了很多例子,其中使用了“using”语句,即

public Item GetItem(long itemId)
    {
        using (var db = new MyEntities())
        {
            return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault();
        }
    }

这里我们创建一个DBcontext MyEntities()的新实例。 我们使用“using”来"ensure the correct use of IDisposable objects."

这只是我经理中的一种方法。但我有十多个。 每次我从管理器调用任何方法时,我将使用“using”语句并在内存中创建另一个DBcontext。垃圾收集器(GC)什么时候处理它们?有谁知道吗?

但是管理器方法有另外一种用法。 我们创建一个全局变量:

private readonly MyEntities db = new MyEntities();

并在没有“using”语句的每个方法中使用DBcontext。方法如下:

public Item GetItem(long itemId)
{
    return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault();
}

问题:

  1. 使用DBcontext变量的正确方法是什么?
  2. 如果我们不使用“usage”语句(因为它会影响性能)怎么办?GC会为此做些什么?
  3. 我是EF使用中的“新手”,但仍然没有找到这个问题的明确答案。

2 个答案:

答案 0 :(得分:13)

我想你会发现很多人提出这种风格的模式。不只是我或亨克 DBContext handling

  • 是,理想情况下使用DBContext子类型的语句
  • 使用Using管理的更好的工作单元模式,具有上下文并处理上下文Just 1 of many UoW examples, this one from Tom Dykstra
  • 工作单位经理应该是新的每个Http请求
  • 上下文不是线程安全的,因此请确保每个线程都有自己的上下文。
  • 让EF在幕后缓存一些东西。
  • 测试上下文创建时间。经过几次Http请求。你还有问题吗?
  • 如果将上下文存储在静态中,则会出现问题。任何类型的并发访问都会受到影响,如果您使用并行AJAX调用,假设使用静态单个上下文时有90%的可能性出现问题。

For some performance tips, well worth a read

答案 1 :(得分:2)

使用DBContext变量的正确或最佳实践方法是使用。

    using (var db = new MyEntities())
    {
        return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault();
    }

好处是许多事情都是我们自动完成的。例如,一旦完成代码块,就会调用dispose。

MSDN EF Working with DbContext

  

创建实例时,上下文的生命周期开始   当实例被处置或垃圾收集时结束。使用   如果您想要上下文控制的所有资源,请使用   布置在街区的尽头。使用时,编译器   自动创建一个try / finally块并调用dispose   最后阻止。