有没有一种实用的方法可以在实体框架4中使用hierarchyID数据类型?

发布于 2024-09-11 11:45:37 字数 845 浏览 0 评论 0原文

就目前而言,实体框架 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 并查看了实现。看起来内部是基于一个名为“OrdTree”的类,我可以使用该类作为重新实现的基础。

  • 为 SQL 编写我自己的 CLR 类型,以处理二进制数据并构建自己的字符串(选项 2 的变体)。不过,这会带来额外的部署问题。

  • 编写一个SQL udf来解析层次结构字符串并将其填充到DB层。缺少数组处理/正则表达式似乎是这里最大的问题。

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

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

所以我的问题是有人解决了这个限制吗?您使用过上述策略吗?如果是这样,怎么办?

As it stands now, the CLR UDTs including HierarchyID aren't supported in Entity Framework 4. HierarchyID.ToString() is useful, but breaks down once any item has 10+ siblings (the basic structure is /3/4/12/ or /3/4/2/ so the 12th node will sort before the 2nd node).

A little more about potential options:

  • Bring back hierarchyID as a varbinary and implement my own binary sorter

  • Bring back hierarchyID as a varbinary and implement my own hierarchyID.ToString() method which pads the numbers with zeros while building the string so the resulting string is sortable (i.e. "/0003/0004/0012/"). I disassebled Microsoft.SqlServer.Types.dll and looked at the implementation. It looks like the interals are based of a class called "OrdTree" and I could use that class as a basis for re-implementation.

  • Write my own CLR type for SQL to work on the binary data and build its own string (a variation of option 2). Although, comes with an added deployment headache.

  • Write a SQL udf to parse the hierarchy string and pad it on the DB layer. The lack of array processing/regex's seems like the biggest issue here.

  • Sort by hierarchyID on the database layer and use the ROW_NUMBER() function as a stand in for sort order.

  • Write some helper methods on the .net layer which re-parse the hierarchyId.ToString() and generate a sortable string (i.e. "/0003/0004/0012/").

So my question is has anyone worked around the limitation? Did you use any of the above strategies? If so, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小梨窩很甜 2024-09-18 11:45:37

嗯,我似乎收到了意见,但没有回应。我有一些直接需要使用 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) + "/";
    }
}

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

Well, I seem to be getting views but no responses. I had some immediate needs to work with the hierarchy structure above SQL, so i put together a static helper class. I don't consider this a complete solution, but so far it works relatively well. PadPath is really the critical function here.

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) + "/";
    }
}

Hope this helps someone! Although, I'd still like to hear from people.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文