C# 在自定义类中实现实体框架的IDisposable
我使用实体框架,比如C# 在自定义类中实现实体框架的IDisposable,c#,entity-framework-6,idisposable,C#,Entity Framework 6,Idisposable,我使用实体框架,比如 public sealed class CacheManagementHelper { private readonly GJobEntities db = new GJobEntities(); public List<User> GetUsers() { return db.Users.ToList(); } } 公共密封类CacheManagementHelper { 私有只读GJobEntities db=新
public sealed class CacheManagementHelper
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
}
公共密封类CacheManagementHelper
{
私有只读GJobEntities db=新GJobEntities();
公共列表GetUsers()
{
返回db.Users.ToList();
}
}
VisualStudio2019女士建议如下
警告CA1001在“CacheManagementHelper”上实现IDisposable
因为它会创建以下IDisposable类型的成员:
“身体”。如果“CacheManagementHelper”以前已发布,
将实现IDisposable的新成员添加到此类型是不允许的
被认为是对现有消费者的突破性改变
我在这里找到了一些线索
但目前还不清楚我是否实现了IDisposable
谢谢你的帮助
但目前还不清楚我是否已经实现了IDisposable
这是一个棘手的问题,有几个答案:
- 不,你不应该李>
- 是的,你应该李>
- 不,你不必
IDisposable
对象应在其生命周期结束时进行处置。关于框架是否能为您处理这个问题,存在一些争论,但这是一种错误的方法。(在底部,在fauly方法下,我将添加原因)
一般来说,处置的责任在于创造者。所以,如果您创建了它,您将对其进行处置
这就是@swdon评论的来源
我在他的代码中看到的最大问题是db是公共的。我不知道是谁正确地处理了这些问题伦敦时间19年8月2日7:07 这就是为什么不应该有公共的非只读IDisposable成员字段。因为:当调用方覆盖它时,您没有简单的方法来跟踪它,那么谁负责调用
Dispose
不,你不应该 国际奥委会 因此,您可能需要使用一个。国际奥委会框架的作用是:;它接管了创建对象的责任,因此,它还负责处理对象。注意:IoC框架的目的不是作为一个工厂,它只是一个副作用 因此,有了国际奥委会,你不会自己创建成员,而是请求它。它可能看起来像这样:
private GJobEntities _context;
//constructor: this object can also be created by the IoC framework.
public CacheManagementHelper (GJobEntities context)
{
//set your field here
_context = context;
}
如果使用此方法,则不必在此处实现idispassable
,因为您不是自己创建对象的,您只需从框架请求上下文,并让它调用Dispose
方法即可
我为什么要提到这一点?因为这是默认的
那么用这个办法,
不,您不应该实现IDisposable,因为您没有创建IDisposable(但是您应该放弃DbContext创建)
是的,你应该 可识别 如果您需要坚持当前的模式(这很有意义),您应该实现
IDisposable
。通过创建IDisPassable成员,您负责处理这些成员。您可以通过实现IDisposable
将其委托给类的创建者
public sealed class CacheManagementHelper : IDisposable
该对象的创建者现在创建IDisposable对象,并负责处理该对象
//keeping it local
public List<User> GetUsers()
{
using (var db = new GJobEntities())
return db.Users.ToList();
}
您唯一的工作是正确实现接口并配置资源
不过,通过阅读文档来正确地实现它还是很不错的。我建议您使用此实现:
那么用这个办法,
是的,您应该实施IDisposable并清理您的资源
不,你不必 或者, 您可以在调用函数时创建上下文,将其保留在本地并在那里进行处理。这样,您就不需要实现
IDisposable
,因为上下文的创建者也在处理它
//keeping it local
public List<User> GetUsers()
{
using (var db = new GJobEntities())
return db.Users.ToList();
}
//将其保留在本地
公共列表GetUsers()
{
使用(var db=new GJobEntities())
返回db.Users.ToList();
}
那么用这个办法,
不,您不必实现IDisposable,因为您没有创建IDisposable成员字段
错误的方法 如果您阅读了“”,您就会知道,如果正确地实现了它,您将非常安全地防范内存泄漏 因此,有人可能会争辩说,您不需要同时调用
Dispose
,因为垃圾收集器将为您执行此操作
这是一种误解
它的问题如下:
- 1) 您不知道正在调用的组件是否正确实现。如果不进行处置(如果使用未经管理的内存),它可能会泄漏
- 2) 内存泄漏是;与时间有关。令人惊讶的hé?请这样看:当您重新启动系统或重新启动应用程序时,内存又回来了。这不是永久性的。从以前开始,这与应用程序的生命周期有关。但是,多线程、无服务器编码等方面的发展确实要求我们对它的看法略有不同。泄漏可能在特定时间范围内发生。一个很好的例子是高内存消耗的图像处理或耗尽连接池李>
最后一句话:EF DbContext通过跟踪所有更改(基本上是一个工作单元),在其生命周期内收集了大量资源。保持一个长寿命的DbContext可能会随着时间的推移导致性能下降。因此,请注意这一点。您必须通过实现
IDisposable
接口,为您的类的消费者提供处理内部db
上下文的可能性:
public sealed class CacheManagementHelper : IDisposable
{
private readonly GJobEntities db = new GJobEntities();
public List<User> GetUsers()
{
return db.Users.ToList();
}
public void Dispose()
{
db.Dispose();
}
}
公共密封类CacheManagementHelper:IDisposable
{
私有只读GJobEntities db=新GJobEntities();
公共列表GetUser