Как выполнить групповое объединение в .NET Core 3.0 Entity Framework? - PullRequest
3 голосов
/ 30 октября 2019

С изменениями в .NET Core 3.0 я получаю

... NavigationExpandingExpressionVisitor 'не удалось. Это может указывать либо на ошибку, либо на ограничение в EF Core. См. https://go.microsoft.com/fwlink/?linkid=2101433 для получения более подробной информации.) ---> System.InvalidOperationException: Обработка выражения LINQ 'GroupJoin, ...

Это действительно простой запрос, поэтому необходимобыть способом выполнить это в .NET CORE 3.0:

 var queryResults1 = await patients
            .GroupJoin(
                _context.Studies,
                p => p.Id,
                s => s.Patient.Id,
                (p, studies) => new 
                {
                    p.DateOfBirth,
                    p.Id,
                    p.Name,
                    p.Sex,
                   Studies =studies.Select(s1=>s1)
                }
            )
            .AsNoTracking().ToListAsync();

Я в основном ищу запрос Linq (или синтаксис метода, как указано выше), который присоединит Исследования к Пациентам и установит Исследования в пустой списокили ноль, если нет исследований для данного пациента.

Есть идеи? Это работало в .NET Core 2.2. Также ссылка MSFT выше упоминает, что изменение взлома ключа связано с оценкой на стороне клиента и предотвращением того, что сгенерированный запрос читает целые таблицы, которые затем должны быть присоединены или отфильтрованы на стороне клиента. Однако с этим простым запросом соединение должно быть легко выполнимым на стороне сервера.

1 Ответ

2 голосов
/ 01 ноября 2019

Как уже говорилось здесь , вы пытаетесь выполнить запрос, который не поддерживается базой данных. EF Core 2 использовал оценку на стороне клиента, чтобы заставить ваш код работать, но EF Core 3 отказывается, потому что удобство на стороне клиента идет за счет трудных для отладки проблем производительности при увеличении набора данных.

Выможно использовать DefaultIfEmpty, чтобы оставить слева присоединиться к исследованиям пациентов, а затем сгруппировать вручную с помощью ToLookup.

var query =
    from p in db.Patients
    join s in db.Studies on p.Id equals s.PatientId into studies
    from s in studies.DefaultIfEmpty()
    select new { Patient = p, Study = s };

var grouping = query.ToLookup(e => e.Patient); // Grouping done client side

В приведенном выше примере получены полные объекты «Пациент» и «Исследование», но вместо этого можно выбрать столбцы «Вишня». Если необходимые вам данные от пациента слишком велики для повторения для каждого исследования, в присоединенном запросе выберите только идентификатор пациента, запрашивая остальные данные пациента в отдельном несвязанном запросе.

...