Я пытаюсь выполнить группирование по запросу к SQL Server с использованием EF Core 2.2, но, похоже, локально выполняется часть внешнего соединения.
Вот запрос:
var payerIds = new int[]{...}
var query = from sr in ctx.DataContext.StatementRecipients
join pf1 in ctx.DataContext.PaymentFacts on sr.RecipientId equals pf1.PayerId into outerJoinPaymentFacts
from pf in outerJoinPaymentFacts.DefaultIfEmpty()
where payerIds.Contains(sr.RecipientId)
group pf.AmountRemaining by sr.RecipientId
into g
select new
{
UserId = g.Key,
UnappliedAmountTotal = g.Sum()
};
И предупреждения:
The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
16:32:28 WRN] The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
[16:32:28 WRN] The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'from PaymentFactEntity pf in {[outerJoinPaymentFacts] => DefaultIfEmpty()}' could not be translated and will be evaluated locally.
[16:32:28 WRN] The LINQ expression 'from PaymentFactEntity pf in {[outerJoinPaymentFacts] => DefaultIfEmpty()}' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'GroupBy([sr].RecipientId, [pf]?.AmountRemaining)' could not be translated and will be evaluated locally.
[16:32:28 WRN] The LINQ expression 'GroupBy([sr].RecipientId, [pf]?.AmountRemaining)' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
[16:32:28 WRN] The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
[warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
16:32:28 WRN] The LINQ expression 'DefaultIfEmpty()' could not be translated and will be evaluated locally.
[warn16:32:28: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'from PaymentFactEntity pf in {[outerJoinPaymentFacts] => DefaultIfEmpty()}' could not be translated and will be evaluated locally.
WRN] The LINQ expression 'from PaymentFactEntity pf in {[outerJoinPaymentFacts] => DefaultIfEmpty()}' could not be translated and will be evaluated locally.
[warn: Microsoft.EntityFrameworkCore.Query[20500]
что дает?
Спасибо @Gert Arnold за совет по неявной группировке.Мой пересмотренный запрос теперь выглядит так:
Но, по его словам, он все еще оценивается локально.
var query = from sr in ctx.DataContext.StatementRecipients
join pf1 in ctx.DataContext.PaymentFacts on sr.RecipientId equals pf1.PayerId into outerJoinPaymentFacts
from pf in outerJoinPaymentFacts.DefaultIfEmpty()
where payerIds.Contains(sr.RecipientId)
select new
{
UserId = sr.RecipientId,
UnappliedAmountTotal = outerJoinPaymentFacts.Sum(x => x.AmountRemaining)
};
Вот еще несколько вещей, которые я пробовал:
1) заменил массив payerids одним значением int payerid.Мне было интересно, если массив форсирует локальную оценку.Не былоДаже когда я фильтрую по одному идентификатору получателя / плательщика, запрос все равно оценивает localy
2) Перед тем как выполнить запрос, я сделал DbContext.SaveChangesAsync (), чтобы сбросить все изменения в локальном контексте обратно вдБ.Моя теория заключалась в том, что в таблицу фактов оплаты были внесены некоторые незавершенные изменения, и эти незафиксированные изменения вынудили локальную оценку, чтобы они могли быть включены в результат.Моя теория не оправдалась, так как запрос все еще оценивался локально.
Есть ли какой-нибудь способ / диагностика, которую мы можем получить от EF-движка, почему он чувствует, что ему нужно запускать эти части локально?