2013-06-02 25 views
2

我知道标题看起来有点坏:)但我不知道如何解释我的问题..哪一个更好,一个实例变量或EF上下文的局部变量?

这通常是我的一个基本的问题,但我不知道答案..

我写一个服务器应用程序正在使用eneter库进行客户端 - 服务器通信,并且它具有一个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类来创建一个 全球 实例变量,并用它为每个功能..?

+0

这不是一个全局变量(甚至不是'static')。 –

+0

@HenkHolterman,我想你明白我的意思..我可以在课堂上使用这个变量..所以如果需要改变,你可以这样做 – ertan2002

回答

2

更重要的是,在你的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(); 
    //.... 
} 

取读here为什么我IDisposable的密封。

+0

感谢您的回答,以及我应该使用(var dal = new MyDal())那样或我的dal是作为局部变量? – ertan2002

+0

@ ertan2002很难理解你在问什么。 'using'语句**中的变量是**局部变量。 – spender

+0

啊对不起,我写错了:我的意思是mydal类的实例变量..就像MyDal dal; – ertan2002

1

这两种方法在变更跟踪的范围方面有很大不同。如果两者都工作得很好,那么请确保使用WithNoTracking

你可以为你的实体创建一个成员变量,就像你的第一个代码一样。但是因为你不能在它周围写出using(){}声明,所以包含的类应该是IDisposable。然后消费类应该在using(){}内使用它。

+0

谢谢你编辑我的标题和答案,以及我要去要使用更改跟踪和另一件事情,我也将使用通用的存储库设计模式.. – ertan2002

1

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

但是,您应该在任何情况下处置创建的上下文,因为它将数据库连接作为本地资源来持有。

如果你想在你的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(); 
    } 
} 

你可以在使用这个类a using block then:

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

如果你没有实现完整的IDisposable模式,你的类**应**被“密封”。 – spender

+0

谢谢你回答slauma,我向你问同样的问题,我需要使用(var helper ...())而不是dbhelper类的位置变量吗?我不能决定哪个更好 – ertan2002

+0

@Spender'sealed'不是一次性模式的要求 - 'protected Dispose(bool disposing)'是多态一次性类型中的常态 - 尽管也许这就是您所说的“完整的一次性模式“ - 在这种情况下,我同意。也许用一些GC.SuppressFinalize。 –

1

这取决于其他方法的存在以及它们的作用。如果要使用ORM进行更改并保持这些更改,则需要创建对象的数据上下文。另外,如果您希望身份管理器在给同一个对象实例提供同样的对象实例两次时,您将需要使用相同的数据上下文 - 因此您需要保持方便。最后,如果该类型使用延迟加载并期望它可以工作 - 那么如果已经处理了数据上下文,那么这将不起作用。

但是,如果您只想在不更改跟踪,延迟加载或身份管理的情况下对数据进行只读访问:急切地进行部署。也许可以考虑像微型ORM这样的事物,它们根本就没有这些功能(故意地,简单而快速)。

+0

谢谢,他们是如此有用的信息,我明白了。 – ertan2002

相关问题