просмотрели многие сообщения здесь, на SO, и не нашли адреса для этого. Просто обратите внимание, что весь представленный здесь код упрощен, но представляет реальный код. У меня есть таблица данных, которая описывает некоторые свойства планов покрытия. Запрос, чтобы вернуть лучший матч выглядит примерно так:Коалесцирующие результаты в Linq
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;
}
Мой вопрос: Есть ли лучший способ (быстрее, меньше кода, меньше повторений), чтобы сделать этот запрос Linq ?
Update: Я закончил с этой функцией в качестве замены:
decimal GetCoveragePercentage(string coverage, string planCode, string stateCode)
{
return Coverages.Where(x => x.Equals(coverage, planCode, stateCode))
.DefaultIfEmpty(Coverages.Where(x => x.Equals(coverage, defaultPlanCode, stateCode)).FirstOrDefault()
?? Coverages.Where(x => x.Equals(coverage, defaultPlanCode, defaultStateCode)).First())
.First().PercentOfCoverageA;
}
DefaultIfEmpty хочет экземпляр вместо с IEnumeration экземпляров. Это привело меня к добавлению First/FirstOrDefault к резервным подзапросам, и выясняется, что DefaultIfEmpty ненавидит его, если вы даете ему нуль, поэтому я использовал оператор коллаборации null для свертывания резервных уровней.
Я не знаю, почему они не дают вам DefaultIfEmpty, который принимает IEnumeration, это будет просто так:
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> defaultValue)
{
return (source != null && source.Any()) ? source : defaultValue;
}
На самом деле, я думаю, я буду использовать этот метод расширения, и есть моя функция такова:
decimal GetCoveragePercentage(string coverage, string planCode, string stateCode)
{
return Coverages.Where(x => x.Equals(coverage, planCode, stateCode))
.DefaultIfEmpty(Coverages.Where(x => x.Equals(coverage, defaultPlanCode, stateCode)))
.DefaultIfEmpty(Coverages.Where(x => x.Equals(coverage, defaultPlanCode, defaultStateCode)))
.First().PercentOfCoverageA;
}
Спасибо! Я не знал о DefaultIfEmpty, это именно то, что я искал, чтобы позаботиться об этой части. Я тоже ненавижу повторение, это довольно грязно. Я буду применять ваши предложения утром и отчитываться. –