我有一个类别表,它具有父母类别,我尝试迭代所有类别,并以逆父母的身份获得父母类别,但是其中一些人返回而没有逆父母的返回未知原因。
类别
public partial class Categories
{
public Categories()
{
InverseParent = new HashSet<Categories>();
}
public int Id { get; set; }
public int? ParentId { get; set; }
public DateTime CreateDate { get; set; }
public bool? Status { get; set; }
public virtual Categories Parent { get; set; }
public virtual ICollection<Categories> InverseParent { get; set; }
}
这就是我尝试迭代它们创建选择列表项目的方式:
var parentCategories = await _context.Categories.
Include(x => x.Parent).
Where(x => x.Status == true).
Where(x => x.Parent != null).
Select(x => x.Parent).
Distinct().
ToListAsync();
foreach (var parent in parentCategories)
{
SelectListGroup group = new SelectListGroup() { Name = parent.Id.ToString() };
foreach (var category in parent.InverseParent)
{
categories.Add(new SelectListItem { Text = category.Id.ToString(), Value = category.Id.ToString(), Group = group });
}
}
因此,问题是我的某些父母类别返回所有孩子类别,有些不返回,我不为什么。
该代码有几个问题,在文档的"加载相关数据"部分中都有一些解释。
首先,您没有要求EF Core包括InverseParent
,因此在逻辑上期望它是始终 null
。
您得到的是以下急切的加载行为的结果:
提示
实体框架核心将自动将导航属性固定到以前加载到上下文实例中的任何其他实体。因此,即使您不明确包含导航属性的数据,如果以前加载了某些或全部相关的实体,该属性仍然可能被填充。
第二,由于查询正在更改其初始形状(Select
,Disctinct
(,因此它被忽略了,包括类别。
话虽如此,您应该以其他方式构建查询 - 直接从父类别开始,包括InverseParent
:
var parentCategories = await _context.Categories
.Include(x => x.InverseParent)
.Where(x => x.InverseParent.Any(c => c.Status == true)) // to match your query filter
.ToListAsync();
包括 Include(x => x.Parent)
时,对于 InverseParent
,您似乎并没有这样做。这可能会准确地影响您的结果。包括它可以解决吗?
parentCategories = await _context.Categories.
Include(x => x.Parent).
Include(x => x.InverseParent).
Where(x => x.Status == true).
Where(x => x.Parent != null).
Select(x => x.Parent).
Distinct().
ToListAsync();
foreach (var parent in parentCategories)
{
SelectListGroup group = new SelectListGroup() { Name = parent.Id.ToString() };
foreach (var category in parent.InverseParent)
{
categories.Add(new SelectListItem { Text = category.Id.ToString(), Value = category.Id.ToString(), Group = group });
}
}
upd:由于您选择x => x.Parent
无论如何都可能需要使用ThenInclude()
方法。