是否有实用的方法在实体框架4中使用hierarchyID数据类型?

时间:2010-07-27 20:51:18

标签: sql-server entity-framework sql-server-2008 entity-framework-4 hierarchical-data

现在,实体框架4中不支持包含HierarchyID的CLR UDT.HierarchyID.ToString()很有用,但是一旦任何项目有10个以上的兄弟节点就会分解(基本结构是 / 3 / 4/12 / / 3/4/2 / 所以第12个节点将在第2个节点之前排序)。

关于潜在选择的更多信息:

  • 将hierarchyID作为varbinary返回并实现我自己的二进制分类器

  • 将hierarchyID作为varbinary返回并实现我自己的 hierarchyID.ToString()方法,该方法在构建字符串时用零填充数字,以便生成的字符串是可排序的(即“/ 0003” / 0004/0012 /“)。我反汇编了 Microsoft.SqlServer.Types.dll 并查看了实现。看起来Interals是基于一个名为“OrdTree”的类,我可以使用该类作为重新实现的基础。

  • 为SQL编写我自己的CLR类型来处理二进制数据并构建自己的字符串(选项2的变体)。虽然,增加了部署头痛。

  • 编写SQL udf来解析层次结构字符串并将其填充到数据库层。缺乏阵列处理/正则表达式似乎是最大的问题。

  • 按数据库层的hierarchyID排序,并使用ROW_NUMBER()函数作为排序顺序的替代。

  • 在.net图层上编写一些帮助方法,重新解析hierarchyId.ToString()并生成可排序的字符串(即“/ 0003/0004/0012 /”)。

所以我的问题是有人解决了这个限制吗?你有没有使用上述任何一种策略?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:4)

好吧,我似乎得到了观点,但没有回应。我有一些立即需要使用SQL上面的层次结构,所以我把一个静态助手类放在一起。我不认为这是一个完整的解决方案,但到目前为止它的工作相对较好。 PadPath确实是这里的关键功能。

public static class SQLHierarchyManipulatin {
    const int   DEFAULT_PAD_LEN     = 3;
    const char  DEFAULT_PAD_CHAR    = '0';

    public static string PadPath(string Hierarchy) {
        return PadPath (Hierarchy, DEFAULT_PAD_LEN);
    }       
    public static string PadPath(string Hierarchy, int padLen) {
        string[]    components  = Hierarchy.Split('/');

        for (var i = 0; i < components.Length; i++ ) {
            if (components[i] != "") {
                components[i] = components[i].PadLeft(padLen, DEFAULT_PAD_CHAR);
            }
        }
        return string.Join("/", components);
    }

    public static int CurrentNodeIndex(string Hierarchy) {
        string[]    components  = Hierarchy.Split('/');
        string      startItem   = components[components.Length - 2]; //one slot back from trailing slash

        return int.Parse(startItem);
    }

    public static string ParentPath (string Hierarchy) {
        return  Hierarchy.Substring(0, Hierarchy.TrimEnd('/').LastIndexOf('/') + 1);
    }

    public static string AppendChildWithPadding (string Hierarchy, int childIndex, int padLen) {
        return AppendChild(Hierarchy, childIndex, DEFAULT_PAD_LEN);
    }
    public static string AppendChildWithPadding (string Hierarchy, int childIndex) {
        return AppendChild(Hierarchy, childIndex, DEFAULT_PAD_LEN);
    }
    public static string AppendChild (string Hierarchy, int childIndex) {
        return AppendChild(Hierarchy, childIndex, DEFAULT_PAD_LEN);
    }
    public static string AppendChild (string Hierarchy, int childIndex, int padLen) {
        return Hierarchy + childIndex.ToString().PadLeft(padLen, DEFAULT_PAD_CHAR) + "/";
    }
}

希望这有助于某人!虽然,我仍然希望听到人们的意见。