EF Core 2.0 не загружает связанные объекты при использовании условия where - PullRequest
0 голосов
/ 25 мая 2018

У меня есть объект с именем Category, который имеет рекурсивные отношения, подобные этому:

public class Category
    {
        public int CategoryId { get; set; }
        public int? ParentCategoryId { get; set; }
        public string Description { get; set; }

        public Category ParentCategory { get; set; }
        public ICollection<Category> Children { get; set; }
        public ICollection<ProductCategory> Products { get; set; }

        public Category()
        {
            Products = new List<ProductCategory>();
            Children = new List<Category>();
        }
    }

Мне трудно понять, почему этот код

return await Context.Set<Category>()
                .Where(c => c.CategoryId == id)
                .OrderBy(c => c.Description)
                .ToListAsync();

возвращает только отфильтрованную категориюбез дочерних элементов, и этот запрос:

return await Context.Set<Category>()
                .OrderBy(c => c.Description)
                .ToListAsync();

возвращает все категории с соответствующими дочерними элементами каждой.Если я добавляю .Include (c => c.Children) к отфильтрованным результатам, он возвращает то, что я ищу.

Главное, что я хочу понять, почему эти запросы возвращают другой результатпо категориям детей.

1 Ответ

0 голосов
/ 25 мая 2018

Первый запрос:

return await Context.Set<Category>()
            .Where(c => c.CategoryId == id)
            .OrderBy(c => c.Description)
            .ToListAsync();

Не возвращает дочерние элементы, потому что вы загружаете только Category, который соответствует идентификатору, предоставленному из базы данных.Если вам нужны дети, вам нужно Include(c => c.Children)

Второй запрос:

return await Context.Set<Category>()
            .OrderBy(c => c.Description)
            .ToListAsync();

Не имеет фильтра, поэтому EF Core загружает все Categories из базы данных.Он содержит дочерние элементы, поскольку эти сущности также загружаются как «родительские» объекты, поэтому Entity будет сопоставлять свойство Navigation с помощью внешних ключей, поскольку сущности уже отслеживаются в контексте.

Например, если высделал это:

Category parentCategory = await Context.Set<Category>()
        .SingleOrDefaultAsync(c => c.CategoryId == id);

List<Category> childCategories = await Context.Set<Category>()
        .Where(c => c.ParentCategoryId == parentCategory.CategoryId)
        .ToListAsync();

Тогда parentCategory заполнил бы его свойство Children, даже если вы их не Include(), а потому что все сущности отслеживались в пределах одной и той же области.DbContext отношения сопоставлены.В приведенном выше коде, если вы поместите точку останова во второй оператор и проверите parentCategory, вы увидите, что его свойство Children не имеет элементов до тех пор, пока вы не выполните второй оператор.

...