EF Core 1.0:如何查询整棵树?
EF Core 1.0: How to query a whole tree?
我正在使用 EF 7.0.0.0-rc1-final。
我有一个具有 one-to-many 关系的树结构,从 GrandGrandParent 到 GrandParent 到 Parent 到 Child:
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; }
}
使用 EF Core 1.0 (EF 7),如何创建一个 LINQ 查询(或使用 sub-queries),在给定特定 grand-grand-parent ID 的情况下为我提供整棵树?
我可以 .Include() 向上或向下一个级别,也许我对显而易见的东西视而不见?这给了我 GrandGrandParent 和 GrandParents:
的列表
var ggparent1 = from ggp in myDbContext.GrandGrandParent
.Include(ggp => ggp.GrandParents)
where ggp.ID == 2
select ggp;
我想获取整棵树,一直到 children 的列表。我必须求助于编写 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 查询。
如果您需要完整的树,则不需要 select
。您可以使用 select 提取结果树的一部分或从层次结构中构建一个新的(平面)对象。
一个示例,其中我将只有两个级别(多对多)的层次结构展平以获取分组 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();
我正在使用 EF 7.0.0.0-rc1-final。
我有一个具有 one-to-many 关系的树结构,从 GrandGrandParent 到 GrandParent 到 Parent 到 Child:
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; }
}
使用 EF Core 1.0 (EF 7),如何创建一个 LINQ 查询(或使用 sub-queries),在给定特定 grand-grand-parent ID 的情况下为我提供整棵树?
我可以 .Include() 向上或向下一个级别,也许我对显而易见的东西视而不见?这给了我 GrandGrandParent 和 GrandParents:
的列表var ggparent1 = from ggp in myDbContext.GrandGrandParent
.Include(ggp => ggp.GrandParents)
where ggp.ID == 2
select ggp;
我想获取整棵树,一直到 children 的列表。我必须求助于编写 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 查询。
如果您需要完整的树,则不需要 select
。您可以使用 select 提取结果树的一部分或从层次结构中构建一个新的(平面)对象。
一个示例,其中我将只有两个级别(多对多)的层次结构展平以获取分组 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();