C# 仅在需要时有条件地处理 Entity Framework DbContext
C# Conditionally disposing of Entity Framework DbContext only when needed
我正在尝试使我的代码足够智能,以便仅在相关方法的当前执行生命周期内需要时才打开和处理 Entity Framework DBcontext。
基本上,如果将真实上下文传递到方法中,那么我不想 处理它。
但是,如果只在相关方法的当前执行生命周期内需要它,那么它将在 finally 块中处理
public int UpSertCompanyStockInfo( Guid companyId, string companyName, float stockPrice, float peRatio, CommunicationEngineDatabase context)
{
bool isContextOnlyCreatedForCurrentMethodExecutionRun = false;
if (context == null)
{
isContextOnlyCreatedForCurrentMethodExecutionRun = true;
context = new CommunicationEngineDatabase();
}
try
{
CompanyStockInfo companyStockInfo = new CompanyStockInfo();
companyStockInfo.CompanyName = companyName;
companyStockInfo.StockPrice = stockPrice;
context.CompanyStockInfoTable.Add(companyStockInfo);
context.SaveChanges();
}
catch (Exception _ex)
{
}
finally
{
if (isContextOnlyCreatedForCurrentMethodExecutionRun == true && context != null)
{
((IDisposable)context).Dispose();
}
}
return 0;
}
问题是我觉得上述代码的代码行数太多了。有人可以告诉我如何缩短它(甚至可以用 using 语句来做)吗?
您可以将逻辑封装在一个 helper disposable 中(这样您就可以利用 using
)class(甚至 struct
),如下所示:
class DbContextScope : IDisposable
{
public static DbContextScope Open<TContext>(ref TContext context) where TContext : DbContext, new()
=> context != null ? NullScope : new DbContextScope(context = new TContext());
static readonly DbContextScope NullScope = new DbContextScope(null);
private DbContextScope(DbContext context) => this.context = context;
readonly DbContext context;
public void Dispose() => context?.Dispose();
}
你的示例的用法是:
public int UpSertCompanyStockInfo( Guid companyId, string companyName, float stockPrice, float peRatio, CommunicationEngineDatabase context)
{
using (DbContextScope.Open(ref context))
{
CompanyStockInfo companyStockInfo = new CompanyStockInfo();
companyStockInfo.CompanyName = companyName;
companyStockInfo.StockPrice = stockPrice;
context.CompanyStockInfoTable.Add(companyStockInfo);
context.SaveChanges();
}
return 0;
}
我正在尝试使我的代码足够智能,以便仅在相关方法的当前执行生命周期内需要时才打开和处理 Entity Framework DBcontext。
基本上,如果将真实上下文传递到方法中,那么我不想 处理它。 但是,如果只在相关方法的当前执行生命周期内需要它,那么它将在 finally 块中处理
public int UpSertCompanyStockInfo( Guid companyId, string companyName, float stockPrice, float peRatio, CommunicationEngineDatabase context)
{
bool isContextOnlyCreatedForCurrentMethodExecutionRun = false;
if (context == null)
{
isContextOnlyCreatedForCurrentMethodExecutionRun = true;
context = new CommunicationEngineDatabase();
}
try
{
CompanyStockInfo companyStockInfo = new CompanyStockInfo();
companyStockInfo.CompanyName = companyName;
companyStockInfo.StockPrice = stockPrice;
context.CompanyStockInfoTable.Add(companyStockInfo);
context.SaveChanges();
}
catch (Exception _ex)
{
}
finally
{
if (isContextOnlyCreatedForCurrentMethodExecutionRun == true && context != null)
{
((IDisposable)context).Dispose();
}
}
return 0;
}
问题是我觉得上述代码的代码行数太多了。有人可以告诉我如何缩短它(甚至可以用 using 语句来做)吗?
您可以将逻辑封装在一个 helper disposable 中(这样您就可以利用 using
)class(甚至 struct
),如下所示:
class DbContextScope : IDisposable
{
public static DbContextScope Open<TContext>(ref TContext context) where TContext : DbContext, new()
=> context != null ? NullScope : new DbContextScope(context = new TContext());
static readonly DbContextScope NullScope = new DbContextScope(null);
private DbContextScope(DbContext context) => this.context = context;
readonly DbContext context;
public void Dispose() => context?.Dispose();
}
你的示例的用法是:
public int UpSertCompanyStockInfo( Guid companyId, string companyName, float stockPrice, float peRatio, CommunicationEngineDatabase context)
{
using (DbContextScope.Open(ref context))
{
CompanyStockInfo companyStockInfo = new CompanyStockInfo();
companyStockInfo.CompanyName = companyName;
companyStockInfo.StockPrice = stockPrice;
context.CompanyStockInfoTable.Add(companyStockInfo);
context.SaveChanges();
}
return 0;
}