C# 对于EF上下文,实例变量和局部变量哪个更好?

C# 对于EF上下文,实例变量和局部变量哪个更好?,c#,entity-framework,idisposable,using-statement,C#,Entity Framework,Idisposable,Using Statement,我知道这个标题看起来有点糟糕:)但是我不知道如何解释我的问题 这对我来说是一个典型的基本问题,但我不知道答案 我正在编写一个服务器应用程序,它使用eNet库进行客户机-服务器通信,并且它有一个DAL从数据库获取数据。由于它是一个服务器应用程序,它总是需要与数据库通信,所以我不知道哪种方法更有效。(大约,最多50个客户端将连接到服务器) 我正在使用实体框架,并从mysql数据库创建了一个模型 第一个代码在这里 private MyEntities ent; public DbHe

我知道这个标题看起来有点糟糕:)但是我不知道如何解释我的问题

这对我来说是一个典型的基本问题,但我不知道答案

我正在编写一个服务器应用程序,它使用eNet库进行客户机-服务器通信,并且它有一个DAL从数据库获取数据。由于它是一个服务器应用程序,它总是需要与数据库通信,所以我不知道哪种方法更有效。(大约,最多50个客户端将连接到服务器)

我正在使用实体框架,并从mysql数据库创建了一个模型

第一个代码在这里

    private MyEntities ent;

    public DbHelper()
    {
     ent = new MyEntities();
    }

   void Foo()
  { 
       ent.Mytable.where......
       ....

  }
第二种类型代码是

    void Foo()
    {
        using (MyEntities ent = new MyEntities())
        {
            ent.Mytable.where...
        }

    }

我是否可以使用using语句或为dal类创建一个全局实例变量,并将其用于每个函数

就变更跟踪的范围而言,这两种方法非常不同。如果两者都能正常工作,则确保使用
而不使用跟踪


您可以像在第一个代码中一样为实体创建成员变量。但是,由于不能在其周围使用(){}语句编写
,因此包含的类应该是
IDisposable
。然后消费类应该在
中使用(){}
使用它

更好的是,在DAL类上实现IDisposable:

public sealed class MyDal implements IDisposable
{
    private MyEntities ent = new MyEntities();

    void Foo()
    { 
       ent.Mytable.where......
       ....

    }

    public void Dispose()
    {
        ent.Dispose();
    }
}
然后

using(var dal = new MyDal())
{
    dal.Foo();
    //....
}

阅读一下为什么我的IDisposable被密封。

从性能角度看,这并不重要。与实际的数据库交互相比,创建上下文实例是一个非常快速的操作

但是,在任何情况下都应该处理创建的上下文,因为它将数据库连接作为本机资源

如果您希望在
DbHelper
类中使用上下文成员,则该类应实现
IDisposable
,以便在处置
DbHelper
实例本身时处置上下文:

public class DbHelper : IDisposable
{
    private MyEntities ent;

    public DbHelper()
    {
        ent = new MyEntities();
    }

    public void Foo()
    {
        //...
    }

    public void Bar()
    {
        //...
    }

    public void Dispose() // implementation of IDisposable
    {
        ent.Dispose();
    }
}
您可以在
块中使用该类,然后:

using (var helper = new DbHelper())
{
     helper.Foo();
     helper.Bar();
} // helper and helper.ent gets disposed now

这取决于其他方法的存在及其作用。如果要使用ORM进行更改并持久化这些更改,则需要创建对象的数据上下文。此外,如果您希望identity manager在两次查询同一事物时为您提供相同的对象实例,则需要使用相同的数据上下文-因此需要将其放在手边。最后,如果该类型使用延迟加载,并且您希望它能够工作,那么如果您已经处理了数据上下文,那么它就不会工作


但是,如果您只希望以只读方式访问数据,而不需要更改跟踪、延迟加载或身份管理:请立即进行处置。也许会考虑一些微小的ORMS,它们没有这些特征(故意,是最小的和快速的)。< /P>这不是一个全局变量(甚至不是代码>静态< /代码>)。HenkHolterman,我想你明白我的意思。我可以在类中使用此变量。。因此,如果需要更改,您可以这样做如果您没有实现完整的IDisposable模式,您的类应该是密封的。
谢谢您的回答slauma,我向您提出了同样的问题,我需要使用(var helper…())而不是dbhelper类的位置变量吗?我不能决定哪一个是better@Spender
sealed
不是一次性模式的要求-受保护的虚拟处置(bool disposing)
是多态一次性类型的标准-尽管可能这就是您所说的“完全一次性模式”-在这种情况下,我同意。当然,这不是一个要求,但是如果您没有提供正确处理子类的工具,那么密封是一个非常好的主意。谢谢您的回答,我应该使用(var dal=new MyDal())像那样或者我的dal是局部变量?@ertan2002很难理解你在问什么。
using
语句中的变量是局部变量。啊,很抱歉我写错了:S我是指mydal类的实例变量。。像MyDal;在DAL类中编写数据访问代码,在需要进行数据访问的地方,将
MyDal
实例包装在using语句中。这意味着当您完成数据访问后,
MyDal
所持有的资源将得到整齐的处理。你们需要你们的MyDal有一个更长的生命周期吗?我知道你们在说什么,是的,若我创建MyDal类的实例变量而不是使用语句是更好还是不更好?因为我的应用程序将是服务器,我怀疑它是否总是创建一个mydal的局部变量,并且在dispose之后它会更好。。只需从mydal创建一个实例,并始终使用它。。看起来更符合逻辑?感谢您编辑我的标题和答案,我将使用更改跟踪和其他功能,我还将使用通用存储库设计模式。。