C#仅在需要时有条件地处置实体框架DbContext

时间:2019-04-25 19:22:52

标签: c# entity-framework dispose using

我试图使我的代码足够智能,仅在有问题的方法的当前执行生命周期内仅在需要时才打开和处理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语句来完成)吗?

1 个答案:

答案 0 :(得分:3)

您可以将逻辑封装在一个可抛弃的辅助类(这样就可以利用using)类(甚至是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;    
}