使用LINQ从数据库中检索树形结构

8

我在数据库中存储了一个组织结构图树形结构。类似于:

ID (int);
Name (String);
ParentID (int)

C#中它由一个类表示,如下:

class Employee
{
int ID, 
string Name, 
IList < Employee> Subs
} 

我想知道如何最好地使用LINQ(我正在使用Entity Framework)从数据库中检索这些值,以填充C#对象。肯定有比获取顶层然后重复调用获取子级等更好的方法。如何最好地做到这一点?
5个回答

3

2
如果您正在使用SQL Server 2008,您可以利用新的HIERARCHYID功能。
组织过去一直在努力解决在数据库中表示树状结构的问题,需要进行大量连接和复杂的逻辑处理,无论是组织层次结构还是定义BOM(物料清单),其中一个成品依赖于另一个半成品/套件项目,而这些套件项目又依赖于另一个半成品或原材料。 SQL Server 2008提供了解决方案,它将整个层次结构存储在数据类型HierarchyID中。 HierarchyID是可变长度的系统数据类型。 HierarchyID用于定位元素在层次结构中的位置,例如Scott是CEO,Mark和Ravi向Scott汇报,Ben和Laura向Mark汇报,Vijay,James和Frank向Ravi汇报。
所以使用可用的新功能,只需返回您需要的数据而不使用LINQ。缺点是,如果需要超出简单根查询之外的任何内容,您将需要使用UDF或存储过程:
SELECT @Manager = CAST('/1/' AS hierarchyid)         
SELECT @FirstChild = @Manager.GetDescendant(NULL,NULL)  

1
我会在实体中添加一个字段来包含父ID,然后将整个表格加载到内存中,将List子项留空。然后使用Linq to Objects迭代对象并填充列表。只有一个数据库查询,所以应该是合理的。

我找到的做法大致是这样的:foreach (Position position in all) { foreach (Position position1 in all) { if (position1.ParentPositionID == position.ID) { if (position.Subs == null) { position.Subs = new List(); } position.Subs.Add(position1); } } }有更好的方法吗? - Emad Gabriel

0

即使使用LINQ,您仍需要两个查询,因为任何单个查询都会复制主要员工,从而导致创建多个(实际上是相同的)员工... 但是,当您创建对象时,可以使用linq将其隐藏一些,这就是您执行第二个查询的时候,类似于以下内容:

var v = from u in TblUsers
        select new {
            SupervisorName = u.DisplayName,
            Subs = (from sub in TblUsers where sub.SupervisorID.Value==u.UserID select sub.DisplayName).ToList()
        };

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接