Оценка клиента EF Core не работает, если самая верхняя проекция содержит вызов метода - PullRequest
0 голосов
/ 18 июня 2020

В документации говорится, что допустимо иметь некоторый код, который нельзя преобразовать в SQL, в последнем вызове Select:

в EF В Core 3.0 мы ограничили оценку клиента только на проекции верхнего уровня (по сути, последний вызов Select ()). Когда EF Core 3.0 обнаруживает выражения, которые нельзя перевести в другое место в запросе, он выдает исключение времени выполнения.

Хотя я использую вызов метода только при последнем вызове Select(), я получаю исключение System.InvalidOperationException с жалобой, что:

LINQ выражение ... не может быть переведено. Либо перепишите запрос в форме, которая может быть переведена, либо явно переключитесь на оценку клиента, вставив вызов AsEnumerable (), AsAsyncEnumerable (), ToList () или ToListAsyn c (). См. https://go.microsoft.com/fwlink/?linkid=2101038 для получения дополнительной информации.

Я могу заставить свой код работать, если я напишу его так:

// this query works find and gets evaluated well
from entity in DbContext.DbSet<MyEntity>
where <... some conditions ... >
select new EntityDto() 
{
    Prop1 = entity.X.Y,
    Prop2 = someMethod(entity.Z.T),
    Prop3 = <some value>,
    ...
    Prop4 = <some value>,
}

The select Предложение в приведенном выше запросе LINQ представляет собой длинный код, поэтому я решил переместить его в другой отдельный частный метод, чтобы получить более читаемый код. Я ожидал, что это сработает из-за того, что говорится в документации:

// this is the code that gets exception at runtime:
from entity in DbContext.DbSet<MyEntity>
where <... some conditions ... >
select CreateDto(entity.X, entity.Z)

Фрагмент кода выше получает исключение, о котором я сказал. Как я могу это решить? Почему EF жалуется на оценку клиента?

1 Ответ

0 голосов
/ 18 июня 2020

Хотя я использую вызов метода только в последнем вызове Select (),

Извините, но «disabled» означает «отключено», а НЕ «отключено», кроме случаев, когда вы использовали его в последнем вызове Select ".

НЕ вызывайте метод. Оберните то, что вы получите, в проект AsEnumerable, THEN (в перечислении) и вызовите метод. Готово.

...