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

时间:2010-01-06 19:17:09

标签: c# entity-framework linq-to-entities

我有一个存储在数据库中的组织结构图树结构。 就像是

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

在C#中,它由类似

的类表示
class Employee
{
int ID, 
string Name, 
IList < Employee> Subs
} 

我想知道如何从数据库中检索这些值以使用LINQ填充C#对象(我正在使用实体框架)的最佳方法

必须要有比调用更高级别然后重复调用以获得潜艇等更好的东西。

如何做到最好?

5 个答案:

答案 0 :(得分:3)

  1. 您可以构建一个内置递归的存储过程。有关SQL Server中的公用表表达式的更多信息,请查看http://msdn.microsoft.com/en-us/library/ms190766.aspx
  2. 您可能希望找到一种不同的(更好的?)方式来建模数据。 http://www.sqlteam.com/article/more-trees-hierarchies-in-sql列出了一种在数据库中建模分层数据的流行方法。更改建模可以允许您创建可以在不递归的情况下表达的查询。

答案 1 :(得分:2)

如果您使用的是SQL Server 2008,则可以使用new HIERARCHYID功能。

  

组织过去一直在努力   用树的表示形式   数据库中的结构很多   加入了许多复杂的逻辑   这个地方,无论是组织   层次结构或定义BOM(Bill of   材料)其中一个成品   依赖于另一个半成品   材料/套件和这些套件   物品依赖于另一半   成品或原材料。

     

SQL Server 2008有解决方案   我们存储整个问题   数据类型中的层次结构   HIERARCHYID。 HierarchyID是一个变量   长度系统数据类型。 HIERARCHYID   用于定位中的位置   像斯科特这样的元素的层次结构   首席执行官兼马克以及拉维   报告给斯科特,本和劳拉   向Mark,Vijay,James和Frank汇报   向拉维汇报。

因此,使用可用的新函数,只需返回所需的数据,而无需使用LINQ。缺点是除了简单的根查询之外,您还需要使用UDF或存储过程:

SELECT @Manager = CAST('/1/' AS hierarchyid)         
SELECT @FirstChild = @Manager.GetDescendant(NULL,NULL)  

答案 2 :(得分:1)

我要向实体添加一个字段以包含父ID,然后我将整个表拉入内存,使List subs为null。 Id然后遍历对象并使用linq填充列表到对象。只有一个数据库查询应该是合理的。

答案 3 :(得分:0)

实体框架查询应该允许您包含相关的实体集,但是在一元关系中,不确定它是如何工作的......

查看此信息以获取更多相关信息:http://msdn.microsoft.com/en-us/library/bb896272.aspx

答案 4 :(得分: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()
        };