[英]Should I dispose DbContext when using Entity Framework Core
我在aspx
文件(.NET Framework 4.6.2项目)中具有以下方法:
public static string SetAvgPeriodDays(int userId)
{
var service = new AveragePeriodDaysService(EfHelper.GetContext());
try
{
return service.SetAveragePeriodDays(userId);
}
catch (Exception e)
{
return e.Message;
}
}
AveragePeriodDaysService
类具有一个接受DbContext
实例的构造函数:
public class AveragePeriodDaysService
{
private readonly MyDbContext _ctx;
public AveragePeriodDaysService(MyDbContext ctx)
{
_ctx = ctx;
}
public string SetAveragePeriodDays(int userId)
{
// main logic goes here...
}
}
这里是EfHelper
类:
public class EfHelper
{
public static MyDbContext GetContext()
{
var options = new DbContextOptionsBuilder<MyDbContext>();
var connectionString = ...
options.UseSqlServer(connectionString);
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
return new MyDbContext(options.Options);
}
}
题。 我应该处置MyDbContext吗? 如果是,我应该如何正确处理?
通常,您永远都不应处置从外部获得的依赖项,因为您永远不知道还有谁使用此依赖项的相同实例。 这意味着AveragePeriodDaysService
无法处理MyDbContext
。 但是SetAvgPeriodDays
确切知道谁将消费MyDbContext
因为它请求创建MyDbContext
,因此它可以并且应该在使用后进行处置。 使用using
关键字:
public static string SetAvgPeriodDays(int userId)
{
using(var ctx = EfHelper.GetContext())
{
var service = new AveragePeriodDaysService(ctx);
try
{
return service.SetAveragePeriodDays(userId);
}
catch (Exception e)
{
return e.Message;
}
}
}
我实际上不太确定正确的模式是什么,但是我通常采用以下方法(类似于.NET Stream
或SafeHandle
类所做的事情):
您的AveragePeriodDaysService
实际上似乎可以控制上下文(将其存储在private readonly
字段中)。 因此,实际上,此类应实现IDisposable
并处理上下文本身。
另一方面,您可能想对不同的“服务”类使用单个上下文,而不必始终创建一个新的上下文。 因此,如果这些类始终放置上下文,将很烦人。
所以我的实现方式是这样的:
public class AveragePeriodDaysService : IDisposable
{
private readonly MyDbContext _ctx;
private readonly bool _ownContext;
public AveragePeriodDaysService(MyDbContext ctx, bool ownContext)
{
_ctx = ctx;
_ownContext = ownContext;
}
protected virtual void Dispose(bool disposing)
{
if (disposing) GC.SuppressFinalize(this);
if (_ownContext) _ctx.Dispose();
}
public void Dispose()
{
Dispose(true);
}
然后,您可以决定创建的实例是否应该负责处理上下文,或者创建者是否需要保持控制权。
当然,如果创建的实例可以控制,则需要正确处置该实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.