просмотрели много постов здесь на SO, и не нашли ни одного такого адреса. Просто обратите внимание, что весь код, представленный здесь, является упрощенным, но представляет реальный код. У меня есть таблица данных, которая описывает некоторые свойства планов покрытия. Запрос на возвращение лучшего соответствия выглядит примерно так:
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?
Обновление: Я получил эту функцию в качестве замены:
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;
}