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

EBa*_*arr 14 sql-server entity-framework hierarchical-data sql-server-2008 entity-framework-4

现在,实体框架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 /").

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

EBa*_*arr 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) + "/";
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这对某人有帮助!尽管如此,我仍然想听听人们的意见。