Linq to SQL或Linq to Entities 4.0是否支持hierarchyid数据类型

时间:2010-04-20 00:18:20

标签: linq-to-sql sql-server-2008 linq-to-entities .net-4.0

他们是否可以使用linq to SQL / Entities 4.0来处理层次结构数据类型?

3 个答案:

答案 0 :(得分:9)

目前,Microsoft系列ORM都不能将CLR用户定义类型(包括内置hierarchyid和地理空间类型)用作列类型。

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

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

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

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

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

    这听起来像是一种痛苦,但如果你从一开始就以这种方式工作,那就不是那么糟糕了。在Microsoft引入hierarchyid类型之前,我正在使用Dennis Forbes的物化路径层次结构,它基于邻接列表并将路径保持为一种非规范化。 hierarchyid使这更容易做到。

    不幸的是,我没有一个完整的工作示例,说明了为保持hierarchyid和邻接列表之间的正确关联所需要做的一切,但是如果你阅读Dennis's article它应该是一个好的开始。不要实现物化路径,而是使用hierarchyid,但请阅读有关使用触发器实现自我维护层次结构的部分。

    如果Microsoft在其ORM中实现了对hierarchyid的支持,则很容易删除邻接列表并专门切换到基于hierarchyid的解决方案。但是由于管理基于hierarchyid的层次结构需要大量的存储过程来维护无论如何(因为你没有获得“自动”ID),你应该习惯于编写大量的SQL关于分层查询的UDF和存储过程抽象。

答案 1 :(得分:0)

总之,没有。反正不是直接的。不过,你可能会work around it similarly to geospatial types。我没试过。

答案 2 :(得分:0)

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

我们已经创建了计算列

    TreeId.ToString()

表示当前的hierarchyid-column和

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

直接父母的。

我们还创建了一个视图,该视图排除了hierarchyid-column并将此视图拖到Dbml图上,并设置了与引用表的关联。

大多数hierarchyid-functions必须采用存储过程的形式。