Luk*_*101 5 linq-to-entities .net-4.0 sql-server-2008 linq-to-sql
他们是否可以使用linq to SQL/Entities 4.0来处理层次结构数据类型?
Microsoft系列ORM当前都不能将CLR用户定义类型(包括内置hierarchyid
和地理空间类型)用作列类型.
如果您在数据库中使用这些,则有两种解决方法:
使用表达式将计算列添加到层次结构表中CAST(hid AS varbinary892))
.您需要确保在Linq使用的每个查询(包括存储过程)中包含此列.然后,将此列添加到实体映射.
此时,您可以扩展实体的部分类,将"real" hierarchyid
列添加为自己的属性,方法是添加Microsoft.SqlServerTypes
对BinaryReader
/的BinaryWriter
类的引用,并将BLOB数据转换为/来自SqlHierarchyId
.
请注意,您无法针对此列编写Linq查询.如果你尝试,你只会得到一个"不支持的翻译"错误.所以请记住,这是一个有限的解决方法.
另一个选项,也就是我通常喜欢的选项,是hierarchyid
在L2S/EF中根本不使用该列.将单独索引的代理自动生成密钥添加到层次结构表中,并将其hierarchyid
视为实现细节.使用UDF和视图实现仅需要代理ID作为参数的分层查询.
这听起来像是一种痛苦,但如果你从一开始就以这种方式工作,那就不是那么糟糕了.在微软推出这种hierarchyid
类型之前,我正在使用Dennis Forbes的物化路径层次结构,它基于邻接列表并将路径保持为一种非规范化. hierarchyid
使这更容易做到.
不幸的是,我没有一个完整的工作示例,说明你需要做些什么来维持a hierarchyid
和邻接列表之间的正确关联,但如果你阅读Dennis的文章,那应该是一个好的开始.不要实现物化路径,hierarchyid
而是使用,但阅读有关使用触发器实现自我维护层次结构的部分.
如果Microsoft确实hierarchyid
在其ORM 中实现了支持,则很容易删除邻接列表并专门切换到基于的解决方案hierarchyid
.但是,由于管理层次各地根据hierarchyid
需要存储过程的转换来维持反正(因为你没有得到"自动"的ID),你应该得到的舒适与周围的分层查询写了很多SQL的UDF和存储过程的抽象.