我有一个名为 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) 添加到过滤结果中,它会返回我正在寻找的内容。
最主要的是我想了解为什么这些查询在子类别方面返回不同的结果。
最佳答案
第一个查询:
return await Context.Set<Category>()
.Where(c => c.CategoryId == id)
.OrderBy(c => c.Description)
.ToListAsync();
未返回子项,因为您仅加载与数据库提供的 ID 匹配的Category
。如果你想要 child ,你需要 Include(c => c.Children)
第二个查询:
return await Context.Set<Category>()
.OrderBy(c => c.Description)
.ToListAsync();
没有过滤器,因此 EF Core 正在从数据库加载所有类别
。它包含子实体,因为这些实体也作为“父”对象加载,因此实体将使用外键映射导航属性,因为实体已经在上下文中被跟踪。
例如,如果您这样做:
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
属性在执行第二条语句之前没有任何项目。
关于c# - EF Core 2.0 使用 where 条件时不加载相关实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50535438/