【问题标题】:How do you model a tree hierarchy in Entity Framework?如何在 Entity Framework 中为树层次结构建模?
【发布时间】:2011-08-03 21:13:08
【问题描述】:

我的任务是构建一个模拟虚拟文件系统的新系统。我的客户要求使用实体框架构建它。我以前处理过类似节点的数据结构,但从未使用实体框架。

在实体框架中构建分层类的最佳方法是什么?所谓分层,我的意思是一个类可以有一个相同类型的父级,并且可以有零个或多个相同类型的子级。

我使用的是 SQL Server 2008 和 Entity Framework 4.0。我应该使用内置的层次结构数据类型,还是使用 ParentID 路由?欢迎提出建议。

【问题讨论】:

    标签: .net sql-server-2008 entity-framework


    【解决方案1】:

    我遇到了同样的问题。我发现使用 hierarchyid 数据类型并仍在使用 EF 4.0 的最佳方法是在层次结构表上构建视图。

    由于视图不可更新,我创建了删除、插入和添加存储过程,并将它们映射到 ORM 中的实体映射。这真的很好用。

    假设你有这张桌子:

    CREATE TABLE [dbo].[NodeHierarchy]
    (
    [Node] hierarchyid NOT NULL,
    [NodeId] int NOT NULL,
    [Level] AS ([Node].[GetLevel]()) PERSISTED,
    [Lineage] AS ([Node].[ToString]()) PERSISTED,
    [RootNode] AS ([Node].[GetAncestor]([Node].[GetLevel]() - 1)) PERSISTED,
    [ParentNode] AS ([Node].[GetAncestor](1)) PERSISTED
    )
    

    现在你在它上面创建这个视图:

    CREATE VIEW [dbo].[NodeHierarchyView]
    AS
    SELECT   ch.NodeId AS [NodeId],
           ch.Node.ToString() AS [Lineage],
     ch.[Level] AS [Level],
     chr.Node.ToString() AS [RootLineage],
     chr.NodeId AS [RootNodeId],
     chp.Node.ToString() As [ParentLineage],
     chp.NodeId AS [ParentNodeId]
    FROM     dbo.NodeHierarchy ch
     LEFT OUTER JOIN NodeHierarchy chr ON
          ch.RootNode = chr.Node
     LEFT OUTER JOIN CompanyHierarchy chp ON
          ch.ParentNode = chp.Node
    

    现在我可以在视图上的模型中创建一个实体并使用 Linq-to-Entities 并获得良好的性能和简洁的代码。

    这是我使用的添加存储过程:

    CREATE PROCEDURE [dbo].[AddNode]
    @NodeId int,
    @ParentNodeId int
    AS
    DECLARE @NewNode hierarchyid;
    DECLARE @ParnetLineage nvarchar(4000);
    
    SELECT  @ParnetLineage = Lineage
    FROM    NodeHierarchy
    WHERE   NodeId = @ParentNodeId
    
    IF @ParnetLineage IS NULL
    BEGIN
        SET @ParnetLineage = N'/';
    END
    
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION
        SET @NewNode = CAST(@ParnetLineage + CAST(@NodeId AS nvarchar (4000)) + N'/' AS hierarchyid);
    
        INSERT NodeHierarchy (Node, NodeId)
        VALUES (@NewNode, @NodeId)
    COMMIT
    
    SELECT @NodeId AS [NewNodeId]
    RETURN 0
    

    我在表上创建了所有需要的索引和约束。在我的解决方案中,视图显示来自其他表的数据,并且过程也处理这些表。

    奥德

    【讨论】:

      【解决方案2】:

      您必须使用 ParentID,因为 hierarchyid data type is not supported by EF(您也可以查看描述的解决方法)。无论如何都要准备好编写存储过程,因为使用 EF 加载层次结构通常很困难。

      【讨论】:

        猜你喜欢
        • 2021-11-28
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 2016-02-09
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多