Linq中的聚结结果

Linq中的聚结结果,linq,optimization,linq-to-objects,coalesce,Linq,Optimization,Linq To Objects,Coalesce,我已经在这里浏览了很多帖子,但是没有找到任何关于这个的。需要注意的是,这里给出的所有代码都是简化的,但都是真实代码的代表。我有一个数据表,它描述了覆盖计划的一些属性。返回最佳匹配的查询如下所示: select coalesce ( (select c.PercentOfCoverageA from CoveragePlans c where c.coverage = :COVERAGE and c.plancode = :PLANCODE and c.statecode = :STATECODE

我已经在这里浏览了很多帖子,但是没有找到任何关于这个的。需要注意的是,这里给出的所有代码都是简化的,但都是真实代码的代表。我有一个数据表,它描述了覆盖计划的一些属性。返回最佳匹配的查询如下所示:

select coalesce
(
(select c.PercentOfCoverageA from CoveragePlans c
where c.coverage = :COVERAGE
and c.plancode = :PLANCODE
and c.statecode = :STATECODE),

(select c.PercentOfCoverageA from CoveragePlans c
where c.coverage = :COVERAGE
and c.plancode = :DEFAULTPLANCODE
and c.statecode = :STATECODE),

(select c.PercentOfCoverageA from CoveragePlans c
where c.coverage = :COVERAGE
and c.plancode = :DEFAULTPLANCODE
and c.statecode = :COUNTRYWIDE)
) as PercentOfCoverageA
from dual
这是一个很小的表(几十行),经常被点击,很少发生更改,所以我想把它放到内存中,并使用Linq来选择数据以加快速度

我有一个函数,它返回第一个匹配项,完全符合我的要求:

decimal GetCoveragePercentage(string coverage, string planCode, string stateCode)
{
    IEnumerable<CoveragePlan> result = Coverages
        .Where(x => x.Coverage == coverage && x.PlanCode == planCode && x.StateCode == stateCode)
        .Select(x => x);

    if (!result.Any())
    {
        result = Coverages
            .Where(x => x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == stateCode)
            .Select(x => x);
    }

    if (!result.Any())
    {
        result = Coverages
            .Where(x => x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == countryWide)
            .Select(x => x);
    }

    return result.First().PercentOfCoverageA;
}
DefaultIfEmpty需要一个实例,而不是实例的IEnumeration。这导致我在回退子查询中添加了First/FirstOrDefault,结果表明,如果给它一个null,DefaultIfEmpty不喜欢它,因此我使用null合并运算符来汇总回退级别

我不知道他们为什么不给你一个默认的IfEmpty,它需要一个IEnumeration,它只是这样:

public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> defaultValue)
{
    return (source != null && source.Any()) ? source : defaultValue;
}

我相信
.Select(x=>x)实际上什么都不做。这样就可以去掉。可以使用union函数连接查询。至于if no results检查,您可以使用此函数
DefaultIfEmpty()
进行调查

我还建议resharper在优化LINQ方面提供建议

我还认为,你应该遵守干巴巴的原则,而不是有这样一行代码:

x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == stateCode
而是将其替换为以下内容:

x.Equals(coverage,defaultPlanCode,stateCode)
我建议您的方法的linq如下所示(确保您添加的linq与方法优化相同):


谢谢我不知道DefaultIfEmpty,这正是我想要处理的部分。我也讨厌重复,它很潮湿。我会在早上应用你的建议,然后回来汇报。
x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == stateCode
x.Equals(coverage,defaultPlanCode,stateCode)
decimal GetCoveragePercentage(string coverage, string planCode, string stateCode)
{
    return Coverages
        .Where(x => x.Coverage == coverage && x.PlanCode == planCode && x.StateCode == stateCode)
        .DefaultIfEmpty(Coverages.Where(x => x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == stateCode))
        .DefaultIfEmpty(Coverages.Where(x => x.Coverage == coverage && x.PlanCode == defaultPlanCode && x.StateCode == countryWide))First().PercentOfCoverageA;

}