У меня была такая же проблема. Я обнаружил, что лучший способ работать с типом иерархии и при этом использовать 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
Я создал все необходимые индексы и ограничения для таблиц. В моем решении представление отображает данные из других таблиц, и процедуры также управляют этими таблицами.
Одед