我有这个模型:
public class Person
{
public string Name { get; set; }
public Person Parent { get; set; }
public virtual ICollection<Person> Children { get; set; }
}
我的问题:我如何归还所有 child ,无论他们有多深?例如,我可以有一个人 Alice,他有一个 child Bob,而他又有一个 child Charlie。这条 parent 和 child 的链条可能会持续 10 个以上的 Persons。在事先不知道爱丽丝有多少 child 的情况下,我如何在查询中返回所有 child ?我目前正在这样做:
using (var ctx = new PersonContext())
{
var result = ctx.People
.Include(x => x.Parent)
.Include(x => x.Children)
.FirstOrDefault();
return result;
}
但这似乎没有加载 Charlie。使用 ctx.Configuration.ProxyCreationEnabled = false; 似乎也没有什么不同。
请您参考如下方法:
除非您确切知道 child 的数量,否则无法加载孙子。所以你要么延迟加载它们,要么你可以显式地递归加载它们......像这样:
private void LoadChildren(DbContext context, Person person)
{
var childCollection = context.Entry(person).Collection(x => x.Children);
if(!childCollection.IsLoaded)
{
childCollection.Load();
foreach(var child in person.Children)
LoadChildren(context, child);
}
}
/* ... */
using (var ctx = new PersonContext())
{
var result = ctx.People
.Include(x => x.Parent)
.FirstOrDefault();
LoadChildren(ctx, result);
return result;
}
如果您可以接受近似值(拥有“最大”数量的孙子),我认为您应该能够使用 Include 的字符串格式来做到这一点>(虽然完全未经测试,只是发布这个供您进行实验):
/* ... */
var numOfGrandChildren = 30; // 30 maximum grandchildren
string childInclude = "";
for(var i = 0; i < numOfChildren; i++)
{
if(childInclude != "") childInclude+=".";
childInclude+="Children";
}
using (var ctx = new PersonContext())
{
var result = ctx.People
.Include(x => x.Parent)
.Include(childInclude)
.FirstOrDefault();
return result;
}
