C# EF Core 1.0:如何查询整个树?
我使用的是EF7.0.0.0-rc1-final 我有一个树状结构,从外祖父母到外祖父母到父母再到孩子,有一对多的关系:C# EF Core 1.0:如何查询整个树?,c#,linq,tree,entity-framework-core,C#,Linq,Tree,Entity Framework Core,我使用的是EF7.0.0.0-rc1-final 我有一个树状结构,从外祖父母到外祖父母到父母再到孩子,有一对多的关系: public class GrandGrandParent { public int ID { get; set; } public string Name { get; set; } public virtual List<GrandParent> GrandParents { get; set; } public Grand
public class GrandGrandParent
{
public int ID { get; set; }
public string Name { get; set; }
public virtual List<GrandParent> GrandParents { get; set; }
public GrandGrandParent()
{
this.GrandParents = new List<GrandParent>();
}
}
public class GrandParent
{
public int ID { get; set; }
public string Name { get; set; }
public virtual GrandGrandParent GrandGrandParent { get; set; }
public virtual List<Parent> Parents { get; set; }
public GrandParent()
{
this.Parents = new List<Parent>();
}
}
public class Parent
{
public int ID { get; set; }
public string Name { get; set; }
public virtual GrandParent GrandParent { get; set; }
public virtual List<Child> Children { get; set; }
public Parent()
{
this.Children = new List<Child>();
}
}
public class Child
{
public int ID { get; set; }
public string Name { get; set; }
public virtual Parent Parent { get; set; }
}
我想得到整棵树,直到孩子们的名单。我必须编写foreach()循环并手动构建树吗?我只需要使用Linq表单:
private static void Test0(ApplicationDbContext myDbContext)
{
var ggparent = myDbContext.GrandGrandParents
.Include(ggp => ggp.GrandParents)
.ThenInclude(gp => gp.Parents)
.ThenInclude(p => p.Children)
.FirstOrDefault(ggp => ggp.ID == 3);
if (ggparent == null)
{
DebugPrint("GrandGrandParent not found");
return;
}
DebugPrint("GrandGrandParent:");
DebugPrint(ggparent);
if (ggparent.GrandParents == null)
{
DebugPrint("GrandParents null");
return;
}
foreach (var gparent in ggparent.GrandParents)
{
DebugPrint(gparent);
if (gparent.Parents == null) continue;
foreach (var parent in gparent.Parents)
{
DebugPrint(parent);
if (parent.Children == null) continue;
foreach (var child in parent.Children)
{
DebugPrint(child);
}
}
}
int changeCount = myDbContext.SaveChanges();
DebugPrint(string.Format("ChangeCount={0}", changeCount));
}
然后,您不必自己进行子查询。但是您可以添加日志来查看EF实际创建的SQL查询
如果需要完整的树,则不需要选择。可以使用“选择”提取结果树的一部分,或从层次结构中构建新的(平面)对象
例如,我仅使用两个级别(多对多)展平层次结构,以获取分组SelectList的项目:
var result =
(from c in dbContext.EventTypes
join j in dbContext.EventType2EventTypes on c.Id equals j.ChildEventTypeId
join p in dbContext.EventTypes on j.ParentEventTypeId equals p.Id
where p.EventTypeLevel == EventTypeLevel.First && c.EventTypeLevel == EventTypeLevel.Second
orderby p.SortOrder, p.Id, c.SortOrder, c.Id
select new SelectListItem
{
Text = c.NameDe,
Value = c.Id.ToString(),
Group = GetParentEventTypeSelectListGroup(p.NameDe)
}).AsNoTracking();
我只想使用Linq表格:
private static void Test0(ApplicationDbContext myDbContext)
{
var ggparent = myDbContext.GrandGrandParents
.Include(ggp => ggp.GrandParents)
.ThenInclude(gp => gp.Parents)
.ThenInclude(p => p.Children)
.FirstOrDefault(ggp => ggp.ID == 3);
if (ggparent == null)
{
DebugPrint("GrandGrandParent not found");
return;
}
DebugPrint("GrandGrandParent:");
DebugPrint(ggparent);
if (ggparent.GrandParents == null)
{
DebugPrint("GrandParents null");
return;
}
foreach (var gparent in ggparent.GrandParents)
{
DebugPrint(gparent);
if (gparent.Parents == null) continue;
foreach (var parent in gparent.Parents)
{
DebugPrint(parent);
if (parent.Children == null) continue;
foreach (var child in parent.Children)
{
DebugPrint(child);
}
}
}
int changeCount = myDbContext.SaveChanges();
DebugPrint(string.Format("ChangeCount={0}", changeCount));
}
然后,您不必自己进行子查询。但是您可以添加日志来查看EF实际创建的SQL查询
如果需要完整的树,则不需要选择。可以使用“选择”提取结果树的一部分,或从层次结构中构建新的(平面)对象
例如,我仅使用两个级别(多对多)展平层次结构,以获取分组SelectList的项目:
var result =
(from c in dbContext.EventTypes
join j in dbContext.EventType2EventTypes on c.Id equals j.ChildEventTypeId
join p in dbContext.EventTypes on j.ParentEventTypeId equals p.Id
where p.EventTypeLevel == EventTypeLevel.First && c.EventTypeLevel == EventTypeLevel.Second
orderby p.SortOrder, p.Id, c.SortOrder, c.Id
select new SelectListItem
{
Text = c.NameDe,
Value = c.Id.ToString(),
Group = GetParentEventTypeSelectListGroup(p.NameDe)
}).AsNoTracking();
数据库是如何设计的?你们有4张桌子,2张还是1张?尽管您的层次结构很奇怪,但表的数量可以指导我们帮助您(特别是在包含和联接方面)。有4个表,每个类一个。选择层次结构是为了以一种通用的方式显示我的问题,因此读者也不必费心去学习业务逻辑。我尝试了以下LINQ的变体:var gparents=来自myDbContext.GrandParent.Include中的gp(gparent=>gparent.grand祖父母)。Include(gparent=>gparent.Parents)。然后Include(childrent=>childrent.Select(child=>child.ID))其中gp.grandgrandgrandparent.ID==2选择gp;但是.ThenClude始终引发异常。异常是什么?System.ArgumentException:属性表达式'children=>{from Parent child in children select[child].ID}'无效。表达式应表示属性访问:“t=>t.MyProperty”。指定多个属性时,请使用匿名类型:“t=>new{t.MyProperty1,t.MyProperty2}”。我的测试应用程序:和上面的EF类。数据库是如何设计的?你们有4张桌子,2张还是1张?尽管您的层次结构很奇怪,但表的数量可以指导我们帮助您(特别是在包含和联接方面)。有4个表,每个类一个。选择层次结构是为了以一种通用的方式显示我的问题,因此读者也不必费心去学习业务逻辑。我尝试了以下LINQ的变体:var gparents=来自myDbContext.GrandParent.Include中的gp(gparent=>gparent.grand祖父母)。Include(gparent=>gparent.Parents)。然后Include(childrent=>childrent.Select(child=>child.ID))其中gp.grandgrandgrandparent.ID==2选择gp;但是.ThenClude始终引发异常。异常是什么?System.ArgumentException:属性表达式'children=>{from Parent child in children select[child].ID}'无效。表达式应表示属性访问:“t=>t.MyProperty”。指定多个属性时,请使用匿名类型:“t=>new{t.MyProperty1,t.MyProperty2}”。我的测试应用程序:和上述EF类。