2015-01-06 100 views
0

我有兩個功能如下 -.NET LINQ表達<Func鍵<T, bool>>性能問題

public IQueryable<RequestSummaryDTO> GetProgramOfficerUSA(Guid officerId) 
{ 
    List<string> officerCountries = UnityProvider.Instance.Get<IProgramOfficerService>().GetPOCountries(officerId).Select(c => c.CNTR_ID.ToUpper()).ToList(); 
    Expression<Func<TaskRequest, bool>> countriesFilter = (a) => officerCountries.Contains(a.tblTaskDetail.FirstOrDefault().tblOrganization.ORG_Country.ToUpper()); 

    Expression<Func<TaskRequest, bool>> USAAndNotDelegated = LinqUtils.And(this.USAFilter(), this.NotDelegatedFilter(officerId)); 
    Expression<Func<TaskRequest, bool>> countriesOrOwned = LinqUtils.Or(countriesFilter, this.OwnedFilter(officerId)); 
    Expression<Func<TaskRequest, bool>> filter = LinqUtils.And(USAAndNotDelegated, countriesOrOwned); 

    return this.Get(filter, TaskRequestState.USA); 
} 



private IQueryable<RequestSummaryDTO> Get(Expression<Func<TaskRequest, bool>> additionalFilter, TaskRequestState? TaskRequestState = null) 
{ 
    var Tasks = this.TaskRequestRepository.List(additionalFilter).Where(x => x.tblTaskDetail.FirstOrDefault().PD_TaskRequestID == x.Id && 
      (x.tblRequestDetail.AD_Status == (int)RequestStatus.Paid || x.tblRequestDetail.AD_Status == (int)RequestStatus.NotConfirmed)); 

    if (TaskRequestState == TaskRequestState.USA) 
    { 
     Tasks = Tasks.Where(w => (w.tblTaskDetail.FirstOrDefault().PD_PStatus == null || w.tblTaskDetail.FirstOrDefault().PD_PStatus == 125)); 
    } 
    else 
    { 
     Tasks = Tasks.Where(w => w.State == null); 
    } 

    return Tasks.ToList().Select(TaskSummaryFactory.CreateDto).AsQueryable(); 
} 

我用表達式>和的IQueryable在LINQ。它應該使用LINQ To SQL而不是LINQ To Objects。表現應該不錯。

但我沒有看到。我相信LINQ會將每個表的數據都拉到內存中,以使用LINQ To Objects進行處理。我沒有看到通過SQL配置文件發送給SQL Server跟蹤的連接sql查詢,但是發現了一堆單獨的表選擇語句。

它需要在10分鐘內從

return Tasks.ToList().Select(TaskSummaryFactory.CreateDto).AsQueryable(); 

得到的東西回報,我知道問題出在

Expression<Func<TaskRequest, bool>> countriesFilter = (a) => officerCountries.Contains(a.tblTaskDetail.FirstOrDefault().tblOrganization.ORG_Country.ToUpper()); 

tblTask​​Detail是一大桌。如果我切換到較小的一個,性能明顯提高。

任何人都可以幫助找出爲什麼錯在那裏。

感謝,

更新1 - 從實體框架的語句在SQL資料記錄都是這樣 -

EXEC sp_executesql的N'SELECT [Extent1] [ORG_ID] AS [ORG_ID],[ [ORG_CreatedBy] AS [ORG_CreatedBy],[Extent1]。[ORG_CreatedOn] AS [ORG_CreatedOn] FROM [dbo]。[tblOrganization] AS [Extent1] WHERE [Extent1]。[ORG_ID] = @ EntityKeyValue1',N'@ EntityKeyValue1 uniqueidentifier',@ EntityKeyValue1 ='E8C3F120-AA40-445E-A8A0-2937F330D347'

他們都只是有個人表選擇臺tement,沒有加入sql語句。

更新2 -

我在更新1中出錯。我錯過了連接SQL語句。問題是生成的SQL太差。有6個嵌套select語句,11個LEFT OUTER JOIN和10個OUTER APPLY。查詢太長,無法在此發佈。執行生成的SQL需要9分鐘。

+0

您是否嘗試過記錄將什麼SQL發送到服務器? –

+0

謝謝@JonSkeet很高興再次見到你。我更新了有關您感興趣的更多信息的問題。 – Don

+0

出於調試目的,您是否可以嘗試將其重寫爲直接LINQ查詢?我的觀點是,查詢太複雜了,無法直接轉換成SQL。特別是對於LING to SQL,這是因爲在解釋LINQ時不擅長工作而出名的。例如,GetProgramOfficerUSA中的兩行代碼很難在SQL中表達。 – Euphoric

回答

0

我已將EF STE 5升級至EF6。現在性能更好。頁面加載時間從12分鐘減少到1.5分鐘。

相關問題