Обновление ядра EF Не удалось перевести выражение LINQ 'x'

Я обновил ядро ​​.net 2.2 до 5

У меня ошибка по поводу ef that

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

public List<CustomerPageModel> GetCustomers(int AccountID)
        {
            return (from p in context.Customers
                    join f in context.Patients on p.ID equals f.CustomerID into ps
                    from t in ps.DefaultIfEmpty()
                    where p.AccountID == AccountID
                    select new CustomerPageModel
                    {
                        ID = p.ID,
                        Name = p.Name,
                        IsActive = p.IsActive,
                        TC = p.TC,
                        Surname = p.Surname,
                        Email = p.Email,
                        Address = p.Address,
                        Phone = p.Phone,
                        Note = p.Note,
                        AccountID = p.AccountID,
                        Pats = string.Join(",", ps.Select(x => x.Name)),
                        PatCount = ps.Count()
                    })
            .GroupBy(p => p.ID)
            .Select(g => g.First())
           .ToList();
        }

Как я могу преобразовать этот код?


person RaptorR    schedule 01.02.2021    source источник
comment
EF Core ПРЕДУПРЕЖДАЕТ ВАС, что способ, которым вы написали свой запрос ... НЕВОЗМОЖНО выполнить весь запрос на сервере СУБД ....... поэтому он будет запускаться (некоторые из них) на клиенте, который может быть действительно плохая работа. В идеале вы хотите, чтобы весь SQL выполнялся на стороне сервера СУБД. Я бы удалил каждый элемент в вашем предложении where / groupby или создании анонимного объекта ... чтобы выяснить, что является нарушением. Как следует из одного ответа, самое подозрительное предложение, если строка.JOIN должна начинаться там. Вы попытаетесь найти способ обойти строку, вызывающую нарушение.   -  person granadaCoder    schedule 02.02.2021
comment
Причина в том, что в EF Core 3 отключена неявная оценка клиентов. Не могли бы вы поделиться своим дизайном модели?   -  person Rena    schedule 02.02.2021
comment
dotnetfiddle.net/1EmjIB   -  person RaptorR    schedule 02.02.2021


Ответы (2)


Ваша проблемная строка:

Pats = string.Join(",", ps.Select(x => x.Name)),

В частности, метод string.Join не переводится в SQL, поэтому в предыдущих версиях EF ему приходилось извлекать данные из базы данных, а затем выполнять в памяти функцию string.Join. Теперь EF явно сообщает вам, что он не может запустить это на сервере базы данных - это критическое изменение, но дизайнерское решение, которое говорит вам (разработчику), что оно могло работать не так эффективно, как вы думали ...

Чтобы исправить это, и на основе вашего конкретного примера кода я бы рекомендовал следующее:

Добавьте свойство массива имен домашних животных в свой CustomerPageModel:

public string[] PetNames {get;set;}

И превратите свойство Pets в вычисляемую строку только для чтения:

public string Pets { get => string.Join(",", PetNames); }

И измените проблемную строку в своем выражении LINQ на:

PetNames = ps.Select(x => x.Name).ToArray()

person Lacutah    schedule 01.02.2021

Я изменил (барашек на подзапрос)

string.Join(",", ps.Select(x => x.Name)) 

to

string.Join(",", (from y in PatientList where y.CustomerID == p.ID select y.Name).ToArray()),

Я сделал группу позже (после толиста)

var test = mylist.GroupBy(p => p.ID)
                .Select(g => g.First())
                .ToList();

задача решена

person RaptorR    schedule 02.02.2021