我有一个类别表,并且有一个父类别,我尝试遍历所有类别并使用“反向父项”获得父项类别,但是其中一些返回原因是未知原因而没有反向父项。
Categories.cs
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 });
}
}
所以问题是我的某些父类别返回了他们所有的子类别,有些却没有,我也不为什么。
答案 0 :(得分:2)
该代码存在多个问题,在文档的Loading Related Data部分中都有一些解释。
首先,您没有要求EF Core包含InverseParent
,所以更合乎逻辑的是期望它总是 null
。
您得到的是以下Eager Loading行为的结果:
提示
Entity Framework Core将自动将导航属性修复为先前加载到上下文实例中的任何其他实体。因此,即使您未明确包含导航属性的数据,如果先前已加载了部分或全部相关实体,该属性仍可能被填充。
第二,由于查询正在更改其初始形状(Select
,Disctinct
),因此它属于Ignored Includes类别。
话虽如此,您应该以其他方式构建查询-直接从父类别开始并包括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();
答案 1 :(得分:0)
虽然您包括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()
方法。