简体   繁体   中英

C# Conditionally disposing of Entity Framework DbContext only when needed

I'm trying to make my code be intelligent enough to only open and dispose of an Entity Framework DBcontext if it's only needed within the Current execution lifetime of the method in question.

Basically, if a real context is being passed into the method then I do Not want to dispose of it. However, if it's only needed for the Current execution lifetime of the method in question then it will disposed in the finally block

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;

}

The problem is that I feel the aforementioned code is too much in terms of lines of code. Could someone please tell me how to shorten it( maybe even do it with the using statement)?

You can encapsulate the logic inside a helper disposable (so you can utilize using ) class (even struct ) like this:

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();
}

And the usage with your sample would be:

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;    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM