Linq to SQL或Linq to Entities 4.0支持hierarchyid数据类型吗?

5
有没有一种使用linq to SQL/Entities 4.0与层次结构数据类型配合工作的方法?
3个回答

9

目前微软的ORM家族都无法使用CLR用户定义类型(包括内置的和地理空间类型)作为列类型。

如果您在数据库中使用这些类型,有两种解决方法:

  1. 在层次结构表中添加一个计算列,表达式为CAST(hid AS varbinary892))。你需要确保在每个查询(包括存储过程)中都包含这个列,以便Linq使用。然后,将列添加到实体映射中。

    此时,您可以扩展实体的部分类,通过添加对Microsoft.SqlServerTypes的引用并使用BinaryReader/BinaryWriter类将BLOB数据转换为/from SqlHierarchyId,添加“真正的”hierarchyid列作为其自己的属性。

    请注意,您不能针对此列编写Linq查询。如果尝试,您将只会得到“不支持的翻译”错误。因此,请记住,这是一个有限的解决方法。

  2. 另一个选择,也是我通常喜欢的选择,是完全不使用L2S/EF中的hierarchyid列。在层次结构表中添加一个单独索引的代理自动增量键,并将hierarchyid视为实现细节。使用UDF和视图来实现仅需要代理ID作为参数的分层查询。

    这听起来很麻烦,但如果从一开始就这样工作,实际上并不那么糟糕。在Microsoft引入hierarchyid类型之前,我正在使用Dennis Forbes的材料化路径层次结构的适应版本,它基于相邻列表并维护路径作为某种反规范化。 hierarchyid使这个过程变得更加容易。

    不幸的是,我没有一个完整的工作示例来维护hierarchyid和相邻列表之间的正确关联,但是如果您阅读Dennis的文章,它应该是一个良好的开端。不要实现材料化路径,改用hierarchyid,但是请阅读有关使用触发器实现自我维护层次结构的部分。

    如果Microsoft在他们的ORM中实现对hierarchyid的支持,那么删除相邻列表并完全切换到基于hierarchyid的解决方案将变得容易。但是由于管理基于hierarchyid的层次结构需要大量存储过程来进行维护(因为您不会得到“自动”ID),因此您应该熟悉编写大量SQL UDF和存储过程抽象层次查询。


哇..非常感谢。我刚决定将hierarchyid转换为blob,然后再将其转换回hierarchyid。我正在研究如何实现这一点。谢谢。 - Luke101

0

我们使用与Aaronaught类似的Linq to SQL解决方案。

我们创建了计算列。

    TreeId.ToString()

针对当前的层次结构ID列和

    [TreeId].[GetAncestor](1).ToString()

针对直接父级。

我们还创建了一个视图,排除了层次结构ID列,并将此视图拖到Dbml图上,并设置与引用表的关联。

大多数层次结构ID功能都需要以存储过程的形式存在。


0
总的来说,不行。至少不能直接这样做。不过你可以尝试类似于地理空间类型的解决方法。我没有尝试过。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接