Есть ли практический способ использовать тип данныхierarchyID в платформе сущностей 4? - PullRequest
14 голосов
/ 28 июля 2010

В нынешнем виде UDT CLR, включая HierarchyID, не поддерживаются в Entity Framework 4. HierarchyID.ToString () полезен, но не работает, если у любого элемента есть 10+ братьев и сестер (базовая структура / 3/ 4/12 / или / 3/4/2 / , поэтому 12-й узел будет сортироваться перед 2-м узлом).

Немного больше о потенциальных опциях:

  • Верните иерархию ID как varbinary и внедрите мой собственный двоичный сортировщик

  • Принеситеверните иерархию в качестве varbinary и реализуйте мой собственный метод ierarchyID.ToString () , который дополняет числа нулями при построении строки, чтобы результирующая строка была сортируемой (то есть "/ 0003/0004/0012 /").Я разобрал Microsoft.SqlServer.Types.dll и посмотрел на реализацию.Похоже, что интегралы основаны на классе под названием «OrdTree», и я мог бы использовать этот класс в качестве основы для повторной реализации.

  • Написать свой собственный тип CLR для работы с SQLдвоичные данные и построить свою собственную строку (вариант 2).Хотя поставляется с дополнительной головной болью при развертывании.

  • Напишите SQL-файл udf для анализа строки иерархии и добавления ее на уровень БД.Отсутствие обработки массивов / регулярных выражений кажется здесь самой большой проблемой.

  • Сортировка по иерархии на уровне базы данных и использование функции ROW_NUMBER () в качестве замены для порядка сортировки.

  • Напишите некоторые вспомогательные методы на уровне .net, которые повторно анализируют иерархию ID.ToString () и генерируют сортируемую строку (т. Е. "/ 0003/0004/0012 /").

Итак, мой вопрос: кто-нибудь обходил ограничения?Вы использовали какую-либо из вышеперечисленных стратегий?Если да, то как?

1 Ответ

4 голосов
/ 30 июля 2010

Ну, я, кажется, получаю взгляды, но никаких ответов. У меня были некоторые насущные потребности работать со структурой иерархии выше 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) + "/";
    }
}

Надеюсь, это кому-нибудь поможет! Хотя я все еще хотел бы услышать от людей.

...