Фильтр включает подсвойство

Вопросы и ответы

Я хочу отфильтровать включения моего результата, основываясь на свойстве включения. Как мне это сделать?

Я использую EF Core и ленивую загрузку.

Например, скажем, у меня есть три класса: Родитель, Ребенок и Игрушка. Иерархия классов выглядит так:

class Родитель
{
    ICollection<Ребенок> Дети;
}

class Ребенок
{
    ICollection<Игрушка> Игрушки;
}

class Игрушка
{
    int Количество;
}

Я хочу получить родителя из EF Core и отфильтровать детей на основе количества игрушек. Например:

var бригада = await родительStore
     .GetParent()
     .Include(parent => parent.Children.Where(child => x.Toys.Any(toy => toy.count > 1));

Возможно ли что-то подобное? Каждый раз, когда я пробую нечто подобное, компилятор жалуется, что выражение LINQ не транслируется.

Ответ

Да, вы можете фильтровать связанные данные в Entity Framework Core, но вам нужно быть внимательным с использованием метода Include, поскольку он не поддерживает фильтрацию напрямую в методе расширения Include. Вместо этого вы можете использовать метод Select, чтобы создать проекцию и фильтровать данные. Вам нужно будет использовать метод ThenInclude для навигации по связанным сущностям.

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

var brigade = await parentStore
    .GetParent()
    .Select(parent => new 
    {
        Parent = parent,
        Children = parent.Children
            .Where(child => child.Toys.Any(toy => toy.Count > 1))
            .ToList()
    })
    .ToListAsync();

В этом примере:

  1. Используется метод Select, чтобы проецировать данные.
  2. Для фильтрации детей используется Where, который применяется к коллекции Children на основе условия (в данном случае, если есть хотя бы одна игрушка с количеством больше 1).
  3. В конце ToList() используется для конвертации отфильтрованного результата в список.

Обратите внимание, что Select позволяет сформировать анонимный объект, который содержит как родительскую сущность, так и отфильтрованную коллекцию детей. Таким образом, вы сможете работать как с родителем, так и с его отфильтрованными детьми.

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

Эта подходящая техника позволяет избежать ошибки компиляции о том, что LINQ-запрос не может быть преобразован. Наслаждайтесь работой с EF Core!

Оцените материал
Добавить комментарий

Капча загружается...