【问题标题】:c# linq traverse hierarchy data from databasec# linq 遍历数据库中的层次结构数据
【发布时间】:2016-11-30 21:48:40
【问题描述】:

我有一个包含客户的数据库表:

Table:  
[Customer]

Fields:  
[Id] Integer  
[ParentId] Integer

除其他外,客户有一个唯一的 Id 和一个指向创建它的客户的 ParentId。 所以,每个客户都可以有子客户,谁可以有子客户等等。

等等:

Customer{ Id = 1, ParentId = 1 }  //Root customer  
Customer{ Id = 123, ParentId = 1}  
Customer{ Id = 456, ParentId = 1}  
Customer{ Id = 789, ParentId = 1}  
Customer{ Id = 321, ParentId = 123 }  
Customer{ Id = 654, ParentId = 123 }  
Customer{ Id = 987, ParentId = 789 }
Customer{ Id = 1010, ParentId = 987 }

我使用 EF 和 LINQ 来查询我的数据。

我需要的是一个 LINQ 查询,以基于一个 Id 将所有 Id 展平。

例如:
ID 1 将返回所有 ID。
ID 123 将返回 321 和 654
ID 789 将返回 987 和 1010

【问题讨论】:

  • 为什么一定要 linq?
  • @ThePerplexedOne - 因为他正在寻找递归子代:789 -> 987 -> 1010
  • 递归链接很难用 sql 来做,因为 EF linq 只是被翻译成 SQL,你需要考虑如何去做there。存储过程或视图可能是最好的选择。或者您可以将所有内容都拉到内存中并在那里执行。
  • 如果你问我,在 EF 中使用自引用 ParentId 而不是可为空的 root 是一种痛苦。至于问题:加载额外实体和执行多个查询之间的权衡是什么?也许看看this answer I recently wrote 另一个问题。基本上,获取层次结构,然后遍历它进行展平。
  • 使用所有受支持的 SQL Server 版本中都可用的 hierarchyid 列,而不是自引用。该列可以被索引,使子检索非常快。

标签: c# entity-framework linq


【解决方案1】:

无法编写可被 EF 转换为 SQL 的递归 linq 查询。所以你有两个选择。

  1. 在 SQL 中编写 recursive Common Table Expression 并将结果映射到您的实体。
  2. 将整个表放入内存并在代码中遍历它。

【讨论】:

  • @FilipCordas 4 年来不是首选方式。 hierarchyid 是一个更好的选择,因为它是可索引的并且更易于使用。它适用于所有受支持的 SQL Server 版本
  • @FilipCordas 是的,就像我写的那样,是一个递归公用表表达式。
【解决方案2】:

这里有一些适用于 SQL 服务器的东西

 var items = db.Database.SqlQuery<Table>(@"with [CTE] as (
        select * from [Table] c where c.[ParentId] = @id
        union all
        select c.* from [CTE] p, [Table] c where c.[ParentId] = p.[Id]
        and c.[ParentId] <> c.[Id]
    )
    select * from [CTE]", new SqlParameter("@Id", 1));
            var data = items.ToList();

您需要执行原始 sql,但它可以工作

【讨论】:

  • 没有必要这样做。您可以使用hierarchyid 并避免自引用。 EF6 通过 NuGet 包支持hierarchyid
  • Sweet 不知道这一点。有示例链接吗?
  • 检查初学者的重复问题,谷歌T-SQL hierarchyidMSDN tutorial 非常非常详细。检查例如Querying 页面以获取查询示例,Populating 以查看如何插入顶级和子条目
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多