13

Tal como está ahora, los UDT de CLR que incluyen HierarchyID no son compatibles con Entity Framework 4. HierarchyID.ToString() es útil, pero se descompone cuando un elemento tiene más de 10 hermanos (la estructura básica es /3/4/12/ o /3/4/2/ por lo que el 12º nodo se ordenará antes del 2do nodo).¿Existe alguna forma práctica de utilizar el tipo de datos hierarchyID en el marco de entidades 4?

Un poco más acerca de las posibles opciones:

  • Traiga detrás hierarchyid como varbinary e implementar mi propio clasificador binario

  • Traiga detrás hierarchyid como varbinary y poner en práctica mi propia hierarchyID.ToString () método que rellena los números con ceros al construir la cadena para que la cadena resultante sea ordenable (es decir, "/ 0003/0004/0012 /"). Desasoclé Microsoft.SqlServer.Types.dll y miré la implementación. Parece que los interales están basados ​​en una clase llamada "OrdTree" y podría usar esa clase como base para la reimplementación.

  • Escriba mi propio tipo de CLR para que SQL trabaje en los datos binarios y cree su propia cadena (una variación de la opción 2). Sin embargo, viene con un dolor de cabeza adicional de implementación.

  • Escriba un SQL udf para analizar la cadena jerárquica y rellenarla en la capa DB. La falta de procesamiento de matriz/expresiones regulares parece ser el mayor problema aquí.

  • Ordene por hierarchyID en la capa de la base de datos y use la función ROW_NUMBER() como un soporte para el orden de clasificación.

  • escribir algunos métodos de ayuda en la capa de .NET que re-analizar el hierarchyId.ToString() y generar una cadena sortable (es decir "/ 0003/0004/0012 /").

Así que mi pregunta es si alguien ha reparado en la limitación? ¿Usaste alguna de las estrategias anteriores? ¿Si es así, cómo?

Respuesta

3

Bueno, parece que estoy recibiendo visitas pero no hay respuestas. Tenía algunas necesidades inmediatas para trabajar con la estructura jerárquica por encima de SQL, así que armé una clase de ayuda estática. No considero que sea una solución completa, pero hasta ahora funciona relativamente bien. PadPath es realmente la función crítica aquí.

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

Espero que esto ayude a alguien! Aunque, me gustaría saber de la gente.

Cuestiones relacionadas