【问题标题】:Linq Lambda Expressin Where Conditions And Performance ProblemLinq Lambda 表达式 Where 条件和性能问题
【发布时间】:2021-07-03 16:57:43
【问题描述】:

我使用 linq lambda 表达式创建了 where 条件以进行报告。我的条件运行非常缓慢或抛出错误。

错误详情:演进超时。

我怎样才能找到正确的查询?

我的代码:

var query = Worker.Members
        .Where(u => string.IsNullOrEmpty(model.TcNumber) || u.TcNumber.Contains(model.TcNumber))
        .Where(u => string.IsNullOrEmpty(model.FullName) || u.FullName.Contains(model.FullName))
        .Where(u => model.BirthYear == null || u.BirthDate.Year >= model.BirthYear)
        .Where(u => model.BirthYearLevel == null || u.BirthDate.Year <= model.BirthYearLevel)
        .Where(u => model.BirthYearLevel == null || u.BirthDate.Year <= model.BirthYearLevel)
        .Where(u => model.GenderId == null || u.GenderId == model.GenderId)
        .Where(u => model.DistrictCode == null || u.Contacts.Any(c => c.DistrictCode == model.DistrictCode && c.IsActive))
        .Where(u => model.StreetCode == null || u.Contacts.Any(c => c.StreetCode == model.StreetCode && c.IsActive))
        .Where(u => model.ExteriorDoor == null || u.Contacts.Any(c => c.ExteriorDoor == model.ExteriorDoor && c.IsActive))
        .Where(u => model.InteriorDoor == null || u.Contacts.Any(c => c.InteriorDoor == model.InteriorDoor && c.IsActive))
        .Where(u => model.DisabledGroupId == null || u.Disableds.Any(d => d.ReportDisabledGroups.Any(c => c.DisabledGroupId == model.DisabledGroupId)))
        .Where(u => model.ContributionTypeId == null || u.Demands.Any(d => d.ContributionTypeId == model.ContributionTypeId && !d.IsDeleted))
        .Where(u => model.DemandStatusId == null || u.Demands.Any(d => d.DemandStatusId == model.DemandStatusId && !d.IsDeleted))
        .Where(u => model.DemandDateStart == null || u.Demands.Any(d => d.DemandDate >= model.DemandDateStart && !d.IsDeleted))
        .Where(u => model.DemandDateEnd == null || u.Demands.Any(d => d.DemandDate <= model.DemandDateEnd && !d.IsDeleted))
        .Where(u => u.IsTcCitizen == model.IsForeign)
        .Where(u => u.IsDisabled == model.IsDisabled)
        .Where(u => u.IsAlive == model.IsAlive);

【问题讨论】:

  • 你的代码没有很好地分解。例如,您重复的代码会多次过滤掉软删除的需求和联系人,从而损害可读性和可能的​​性能;请改用let 子句。但是,如果没有查询提供程序,就不可能知道代码的性能。是EF吗?如果有,是什么版本?
  • EF 版本为 6.0.0.0
  • 在发布有关查询性能的问题之前,请先查看查询计划。

标签: c# linq lambda


【解决方案1】:

这里正确的模式(假设Worker.Members是一个IQueryable,而不是一个IEnumerable)是有条件地添加条件,像这样:

var query = Worker.Members;

if (!string.IsNullOrEmpty(model.TcNumber))
    query = query.Where(u => u.TcNumber.Contains(model.TcNumber));
if (!string.IsNullOrEmpty(model.FullName)
    query = query.Where(u => u.FullName.Contains(model.FullName));
if (!model.BirthYear == null)
    query = query.Where(u => u.BirthDate.Year >= model.BirthYear);
. . .

【讨论】:

  • 不知道为什么这被否决了。在 EF6 中,这些内联的 null 检查会直接转换为生成的 SQL,并且可能对查询计划非常不利。
【解决方案2】:

【讨论】:

  • 不清楚您所说的连接的对象集合是什么意思,并且您对数据库交互的数量不正确。如果是这种情况,它可能不会超时,而是慢慢地运行
猜你喜欢
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多