EF-查詢緩存


同一個DbContext實例,EF會對查詢過的數據進行緩存。對DbContext的生存期的管理需根據當前的應用來處理(如web、win),盡量不要采用全局的DbContext。也可在查詢中采用AsNoTracking避免從緩存中取數據。

1、問題

構建一個全局的或某個業務場景內唯一的DbContext

public OTBll()
{
  efContext = new AppDbContext();
  this.OT_DataFlowRepository = new EFRepository<OT_DataFlow>(efContext); 

在此場景內間隔查詢數據

HR_SignSealPdf entity =context.HR_SignSealPdf.FirstOrDefault(e =>
  e.SignId == item.SignId && e.Cate == item.Cate);
entity.PdfUploadErrs += 1;

  

SSMS修改PdfUploadErrs后,仍會從entity.PdfUploadErrs的值上累加

UPDATE HR_SignSealPdf SET PdfUploadErrs=0

  

2、解決辦法

(1)每次構建一個新的DbContext實例,使用完畢就釋放

using (var context = new AppDbContext())
{
...
}

(2)AsNoTracking返回新的查詢實體

efContext.HR_SignSealPdf.AsNoTracking()

反編譯的代碼

/// <summary>返回一個新查詢,其中返回的實體將不會在 <see cref="T:System.Data.Entity.DbContext" /> 或 <see cref="T:System.Data.Entity.Core.Objects.ObjectContext" /> 中進行緩存。此方法通過調用基礎查詢對象的 AsNoTracking 方法來運行。如果基礎查詢對象沒有 AsNoTracking 方法,則調用此方法將不會有任何影響。</summary>
    /// <returns>應用 NoTracking 的新查詢,如果不支持 NoTracking,則為源查詢。</returns>
    /// <param name="source">源查詢。</param>
    public static IQueryable AsNoTracking(this IQueryable source)
    {
      System.Data.Entity.Utilities.Check.NotNull<IQueryable>(source, nameof (source));
      DbQuery dbQuery = source as DbQuery;
      if (dbQuery == null)
        return QueryableExtensions.CommonAsNoTracking<IQueryable>(source);
      return (IQueryable) dbQuery.AsNoTracking();
    }

  

3、優化

(1)web端可考慮在當前操作線程內定義個唯一的DbContext,以提高效率

//返回當前線程內的數據庫上下文,如果當前線程內沒有上下文,那么創建一個上下文,並保證上線問實例在線程內部是唯一的
public static VpoEntities GetCurrentDemoContext()
{
	//CallContext:是線程內部唯一的獨用的數據槽(一塊內存空間)
	//傳遞DbContext進去獲取實例的信息,在這里進行強制轉換。
	VpoEntities dbContext = CallContext.GetData("DbContext") as VpoEntities;
	if (dbContext == null) //線程在數據槽里面沒有此上下文
	{
		dbContext = new VpoEntities(); //如果不存在上下文的話,創建一個EF上下文
		var adapter = (IObjectContextAdapter)dbContext;
		var objectContext = adapter.ObjectContext;
		objectContext.CommandTimeout = 1800;

		//我們在創建一個,放到數據槽中去
		CallContext.SetData("DbContext", dbContext);
	}
	return dbContext;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM