他们是否可以使用linq to SQL / Entities 4.0来处理层次结构数据类型?
答案 0 :(得分:9)
目前,Microsoft系列ORM都不能将CLR用户定义类型(包括内置hierarchyid
和地理空间类型)用作列类型。
如果您在数据库中使用这些,则有两种解决方法:
将计算列添加到层次结构表中,表达式为CAST(hid AS varbinary892))
。您需要确保在Linq使用的每个查询(包括存储过程)中包含此列。然后,将此列添加到实体映射。
此时,您可以通过添加对hierarchyid
的引用并使用Microsoft.SqlServerTypes
/ {来扩展实体的分部类,以将“真实”BinaryReader
列添加为其自己的属性{1}}类将BLOB数据转换为BinaryWriter
。
请注意您无法针对此列编写Linq查询。如果你尝试,你只会得到一个“不支持的翻译”错误。请注意,这是有限解决方法。
另一个选项,也就是我通常喜欢的选项,就是不要在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必须采用存储过程的形式。