EF Core 5.0 Union Linq Query с вложенными выборками не работает

Цель:

Я хочу объединить информацию из двух таблиц (entityA и entityB) с разными свойствами в один unionDto. Я пытаюсь реализовать это с помощью операции объединения для одновременной фильтрации различных сущностей в базе данных.

Но для структуры, которую я использую, требуются версии, которые необходимо отфильтровать перед запросом на объединение.

Некоторая дополнительная информация:

В последнем запросе я пытаюсь сделать следующее: сначала я проецирую информацию из таблицы entityA и entityB в универсальный "анонимный" тип (с объединением). Затем я пытаюсь применить разбиение на страницы, а затем я пытаюсь "спроецировать" новый анонимный результат на UnionDto. Таким образом, это приведет к одному UnionDto, который будет иметь "информацию из двух разных таблиц".

Я создал пример своей проблемы с двумя объектами, у которых есть версии:

Сущности:

class entityA {
    public List<VersionA> Versions;
    public Guid CreatedBy;
}

class entityB {
    public List<VersionB> Versions;
    public Guid CreatedBy;
}

class VersionA {
    public string TitleA;
    public Instant EffectiveTo;
}

class VersionB {
    public string TitleB;
    public Instant EffectiveTo;
}

class UnionDto{
    public string Title;
    public Guid Creator;
}

Я задаю такой запрос:

var queryA = databaseContext.Set<entityA>()
                .Select(entity => new
                {
                    Versions = entity.Versions
                        .Where(version => version.EffectiveTo > now)    /* Filtering newest entity Version */ 
                        .Select(versionDetail => new               /* Selecting only the Title of this Version */
                        {
                            Title = versionDetail.TitleA
                        })
                        .ToList(),
                    Creator = entity.CreatedBy,
                });

var queryB = databaseContext.Set<entityB>()
                .Select(entity => new
                {
                    Versions = entity.Versions
                        .Where(version => version.EffectiveTo > now)
                        .Select(versionDetail => new 
                        {
                            Title = versionDetail.TitleB
                        })
                        .ToList(),
                    Creator = entity.CreatedBy,
                });

Выполнение запроса:

var unionDto = await queryA
                .Union(queryB)
                .Skip(0)
                .Take(20)
                .Select(x => new UnionDto
                {
                    Title= x.Versions.FirstOrDefault() == null ? null : 
                        x.Versions.FirstOrDefault().Title,
                    Creator= x.Creator,
                })
                .ToListAsync();

Похоже, что я не могу использовать подвыборки внутри запроса на объединение, и я получаю следующую ошибку:

Установить операции: поддержка при размещении после оценки клиента в проекции #16243

Я не знаю, что мне нужно сделать, чтобы обойти эту проблему, так как я действительно не хочу обрабатывать все свои объекты отдельно с отдельными запросами к базе данных.

В настоящее время используется ядро ​​Ef Версия: 5.0.100-превью

Это просто пример. Это потребовалось бы как минимум для 10 объектов, что привело бы к высокому трафику базы данных, если бы это было сделано для каждого объекта отдельно.

Есть идеи?

2 ответа

Если вам нужен только заголовок первой версии из каждого набора записей, ваш запрос можно упростить, и EF Core сможет перевести этот запрос.

 var queryA = 
    from entity in databaseContext.Set<entityA>()
    from version in entity.Versions
    where version.EffectiveTo > now
    select new 
    { 
       Title = version.Title, 
       Creator = entity.CreatedBy 
    }

 var queryB = 
    from entity in databaseContext.Set<entityB>()
    from version in entity.Versions
    where version.EffectiveTo > now
    select new 
    { 
       Title = version.Title, 
       Creator = entity.CreatedBy 
    }

 var versions = queryA.Union(queryB);

 var unionDto = await versions
            .Skip(0)
            .Take(20)
            .Select(x => new UnionDto
            {
                Title = x.Title,
                Creator = x.Creator,
            })
            .ToListAsync();

EF Union set Отслеживается с помощью операций Set над проекциями, не являющимися сущностями, с разными аспектами. Проблема

Теперь исправлено с помощью EF8 Preview 3, как показано здесь.

Другие вопросы по тегам