我可以将实体框架上下文保留为类变量吗?

Posted

技术标签:

【中文标题】我可以将实体框架上下文保留为类变量吗?【英文标题】:Can I keep Entity Framework context as class variable? 【发布时间】:2018-10-26 20:20:11 【问题描述】:

我习惯于在每种方法中尽可能快地连接/打开/关闭数据库连接。我现在正在使用实体框架,所以我的方法都做这种事情:

using (var context = new FooEntities()) 
    // linq to sql query here

有人告诉我,使用 Entity Framework,我实际上可以让 context 变量成为类级别变量,而不必在每个方法中实例化它。真的是这样吗,还是我应该在每种方法中继续这种模式?

如果有区别,我正在使用 5.0.0 版的框架。

【问题讨论】:

嗯,这完全取决于你在做什么,但最好还是尽可能晚地创建上下文并尽快终止它。 这是 MVC 吗? Here are 3 options。我更喜欢带有基本控制器类的 IoC。 @SteveGreene 这是一个 Web Api 2 项目,而不是 MVC。 主要 IoC 的句柄 Web Api。 我在看你指给我的 ninject 东西。不幸的是,当我执行 NuGet 安装时,文档说将创建的内核配置文件没有被创建。我会继续使用它,因为这看起来是一个很好的解决方案 【参考方案1】:

您可以将 Context 作为类的属性,但您必须考虑如何控制 Context 的处置。例如:

public class UnitOfWork:IDisposable

    public DbContext Context  get; set; 


    public UnitOfWork()
    
        Context = null; //initialize context here
    

    public void DoWorkWithContext1()
    
        //anything you need
    

    public void DoWorkWithContext2()
    
        //anything you need
    

    public void Dispose()
    
        if (Context != null)
            Context.Dispose();
    

那么你会这样使用这个类:

     using (var unit= new UnitOfWork())
        
            unit.DoWorkWithContext1();
            unit.DoWorkWithContext2();
        

【讨论】:

这很糟糕。您使用上下文设置一个属性,它是从这个 Repository 类外部创建的。这意味着存储库不控制上下文的创建。如果该类不控制上下文的创建,则不应处置它。任何在这个 repo 之外使用上下文的人都会得到一个 ObjectDisposedException。【参考方案2】:

这取决于你期望它如何行动。您希望它保留的唯一原因是您是否想在多个方法调用中使用 DbContext 的缓存功能。但由于无论如何它都会从池中拉出连接,因此在创建新的 DbContext 时,处理 DbContext 不应该真正影响性能。

就我个人而言,我尽可能地创建上下文并尽快将其终止。因此,如果您不关心稍后尝试更新它们,Get 调用应该使用 AsNoTracking() 来大大加快调用速度。您还可以创建一个 DbContextFactory,以便每个类都可以控制它认为合适的交互。 (即方法 A 总是创建一个新方法,但方法 B 和 C 可以共享,如果其中任何一个先调用)。虽然,这可能会导致其自身的问题,但您可以选择接受这些条件。

【讨论】:

以上是关于我可以将实体框架上下文保留为类变量吗?的主要内容,如果未能解决你的问题,请参考以下文章

将实体框架与 SQLCE 一起使用时出现奇怪的异常

将对象添加到实体框架上下文大约需要 1.5 秒

当我从未将实体添加到上下文时,实体框架错误地保存了它

实体框架分离实体和相关实体消失

实体框架 6:在上下文中禁用跟踪时更新实体

清除异常时的实体框架上下文