我的任务是构建一个模拟虚拟文件系统的新系统。我的客户已经强制要求使用Entity Framework构建它。我之前处理过类似节点的数据结构,但从未处理过Entity Framework。
在Entity Framework中构建分层类的最佳方法是什么?通过分层,我的意思是一个类可以拥有相同类型的父类,并且可以有零个或多个相同类型的子类。
我正在使用SQL Server 2008和Entity Framework 4.0。我应该使用内置层次结构数据类型,还是使用ParentID路由?建议是最受欢迎的。
答案 0 :(得分:6)
我遇到了同样的问题。我发现使用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
我在表上创建了所有需要的索引和约束。在我的解决方案中,视图显示来自其他表的数据,并且过程也操纵这些表。
乌迪德
答案 1 :(得分:3)
您必须使用ParentID,因为hierarchyid data type is not supported by EF(您还可以检查所描述的解决方法)。无论如何,准备编写存储过程,因为使用EF加载层次结构通常很难。