.NET LINQ表达式<func <t,bool =“”>&gt;性能问题</func <t,>

时间:2015-01-06 21:56:31

标签: performance linq express lambda

我有两个功能如下 -

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

我使用了Expression&gt;和LINQ中的IQueryable。它应该使用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 Profile的实体框架中的语句都是这样的 -

exec sp_executesql N'SELECT [Extent1]。[ORG_ID] AS [ORG_ID],[Extent1]。[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'

他们都只是拥有单独的表select语句,没有加入sql语句。

更新2 -

我在更新1中出错了。我错过了连接SQL语句。问题是生成的SQL太差了。有6个嵌套的select语句,11个LEFT OUTER JOIN和10个OUTER APPLY。查询太长,无法在此处发布。执行生成的SQL需要9分钟。

1 个答案:

答案 0 :(得分:0)

我已将EF STE 5升级为EF6。现在表现更好。页面加载时间从12分钟减少到1.5分钟。