這個問題不是關於entityframework本身的異步問題,如討論的here。EF-Core方法調用LINQ性能
在方法CalculateSomething
中,您可以看到兩個LINQ調用。 第一次LINQ調用(初始化爲result
)的性能絕對沒問題。
但是,第二次LINQ-Call(初始化resultWithDate
)的性能比第一次慢。
第一個需要2秒,第二個需要15-20秒。
dataBase
是我的DbContext
類。 Iam使用實體框架核心。
private async Task<long> CalculateSomething(string numberOne, MyStatus status)
{
var result = await this.dataBase.Something.CountAsync(item => item.NumberOne== numberOne && item.Status == (short)status);
var resultWithDate = await this.dataBase.Something.CountAsync(item => item.NumberOne== numberOne && item.Status == (short)status && !this.IsOlderThan30Days(item.Date));
return result;
}
private bool IsOlderThan30Days(DateTime? itemDate)
{
bool result = true;
if (itemDate.HasValue)
{
if ((DateTime.Now - itemDate.Value).TotalDays <= 30)
{
result = false;
}
}
return result;
}
的問題不是方法調用IsOlderThan30Days
,這個問題是關於CountAsync
。我知道這是因爲我有這樣的事情:
private async Task<long> CalculateAmountOfOrders(string numberOne, MyStatus status)
{
var result = this.dataBase.Something.Where(item => item.NumberOne == numberOne && item.Status == (short)status);
var resultWithDate = this.dataBase.Something.Where(item => item.NumberOne == numberOne && item.Status == (short)status && !this.IsOlderThan30Days(item.Date));
var resultCount = await result.CountAsync();
var resultWithDateCount = await resultWithDate.CountAsync();
return resultCount;
}
而且性能損失出現在兩個CountAsync()
電話。 CountAsync
對resultWithDateCount
花了15秒,而CountAsync
對resultCount
只花了2秒。初始化result
和resultWithDate
同樣快。
我做錯了什麼?
謝謝
您是否可以在每次操作後嘗試處理上下文並重做測試?就像'使用(var db = new Context()){countOperation(); }' 其他:你確定你的查詢是通過EF執行的嗎?因爲我不認爲EF可以通過LinqToEntities來處理'IsOlderThan30Days' ... – Atlasmaybe
'初始化結果和resultWithDate同樣快。'這是因爲在你的後面的代碼中,初始化結果和resultWithDate實際上並沒有做初始化非常。請參閱https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/query-execution。 – mjwills
由於您在seocond查詢中使用了方法('IsOlderThan30Days()'),因此它在內存中執行(因爲該私有方法無法轉換爲/在SQL中執行)。因此,EF必須在使用where表達式進行篩選之前加載所有項目,這很可能是導致性能差異的原因。 (你可以檢查'result'和'resultWithDate'的類型嗎?如果我是正確的,那麼第一個查詢是'IQueryable',而另一個是'IEnumarable') – bassfader