代码之家  ›  专栏  ›  技术社区  ›  Luke101

linq to sql或linqtoentities4.0是否支持hierarchyid数据类型

  •  5
  • Luke101  · 技术社区  · 15 年前

    它们是使用linq to sql/entities 4.0处理层次结构数据类型的方法吗?

    3 回复  |  直到 14 年前
        1
  •  9
  •   Aaronaught    15 年前

    微软的orms家族目前都不能使用clr用户定义的类型(包括内置的 hierarchyid 和地理空间类型)作为列类型。

    如果在数据库中使用它们,则有两个解决方法:

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

      此时,您可以扩展实体的部分类以添加“real” 层次结构 通过添加对 Microsoft.SqlServerTypes 使用 BinaryReader / BinaryWriter 将blob数据转换为/从的类 SqlHierarchyId .

      注意 不能针对此列编写LINQ查询 . 如果你尝试的话,你会得到一个“不支持翻译”的错误。所以请记住这是一个 有限的 解决问题。

    2. 另一种选择,也是我通常喜欢的一种,是不使用 层次结构 在L2S/EF内的柱。向层次结构表中添加一个单独索引的代理项auto inc键,并处理 层次结构 作为实现细节。使用udf和视图实现只需要代理项id作为参数的层次查询。

      这听起来很痛苦,但如果你从一开始就这样工作,其实也没那么糟糕。在微软推出 层次结构 类型,我使用了Dennis Forbes的物化路径层次结构的一个改编,它基于一个邻接列表,并将路径保持为一种非规范化。 层次结构 这样做容易多了。

      不幸的是,我没有一个完整的工作示例来说明您需要做什么来保持 层次结构 和邻接表,但如果你读到 Dennis's article 这应该是个好的开始。不要实现物化路径,使用 层次结构 相反,请阅读有关使用触发器实现自维护层次结构的部分。

      如果微软真的支持 层次结构 在他们的orms中,很容易删除邻接列表并切换到基于 层次结构 . 但是由于管理基于 层次结构 需要一系列存储过程来维护 无论如何 (因为您没有“自动”id),所以您应该习惯于围绕分层查询编写大量的sql udf和存储过程抽象。

        2
  •  0
  •   Craig Stuntz    15 年前

    一句话,不。反正不是直接的。你也许可以 work around it similarly to geospatial types 但是。我没试过。

        3
  •  0
  •   Ville    14 年前

    我们使用与aaronaught的linq to sql类似的解决方案。

    我们已经创建了计算列

        TreeId.ToString()
    

    对于当前的hierarchyid列和

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

    直接父母的。

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

    不过,大多数hierarchyid功能需要以存储过程的形式出现。