我知道标题看起来有点糟糕:)但是我不知道如何解释我的问题…
这对我来说是一个典型的基本问题,但我不知道答案。
我正在编写一个服务器应用程序,该应用程序使用入口库进行客户端-服务器通信,并且它有一个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类创建一个全局实例变量,并将其用于每个函数。div ?
更好的是,在您的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
块中使用这个类:
using (var helper = new DbHelper())
{
helper.Foo();
helper.Bar();
} // helper and helper.ent gets disposed now
这取决于是否存在其他方法以及它们的作用。如果希望使用ORM进行更改并持久化这些更改,则需要创建对象的数据上下文。此外,如果您希望身份管理器在两次查询相同的内容时为您提供相同的对象实例,则需要使用相同的数据上下文—因此需要将其放在手边。最后,如果类型使用延迟加载,并且您希望它能够工作,那么如果您已经处理了数据上下文,那么它将无法工作。
但是,如果您只想要对数据进行只读访问,而不需要更改跟踪、延迟加载或身份管理:请急切地dispose。也许可以考虑像micro- orm这样的东西,它们根本没有这些功能(故意的,为了最小化和快速)。
这两种方法在变更跟踪的范围方面非常不同。如果两者都能很好地工作,那么确保使用WithNoTracking
。
您可以像在第一个代码中那样为实体创建成员变量。但是因为不能在它周围写using(){}
语句,所以包含它的类应该是IDisposable
。然后消费类应该在using(){}
中使用它。