2016-03-29 7 views
0

Ich möchte eine flache Daten in hierarchische mit Dapper konvertieren. Die Prozedur gibt mir Daten die folgende Klasse zu füllen:Konvertieren von flachen Daten in hierarchische mit Dapper C#

public class Supervisor 
    { 
     public string SupervisorID { get; set; } 
     public string ParentSupervisorID { get; set; } 
     public string Name { get; set; } 
     public string Location { get; set; } 
    } 

Ich mag die Daten in folgenden Klasse-Format abgerufen konvertieren:

public class Supervisor 
    { 
     public string SupervisorID { get; set; } 
     public string ParentSupervisorID { get; set; } 
     public string Name { get; set; } 
     public string Location { get; set; } 
     public List<Supervisor> ChildSupervisor { get; set; } 
    } 

Ich habe versucht dies über adrett zu erreichen, wie folgt:

return connection.Query<Supervisor, Supervisor, Supervisor>("***PROCEDURE CALL***", 
         (parent, child) => 
         { 
          if (parent.childData == null) 
           parent.childData = new List<Supervisor>(); 

          parent.childData.Add(child); 
          return parent; 
         }, p, "ParentSupervisorID").ToArray(); 

Können Sie mir bitte führen Sie mich, um das gewünschte Ergebnis zu erreichen.

Dank Sid

Antwort

0

Was Sie brauchen, ist ein Ergebnis, wo 1 to n complex mapping ist es, in einem bestimmten Supervisor collection Sie List of Supervisor davon wollen dieses ein Parent Supervisor wäre. Es gibt keinen aus dem Box-Mechanismus, vor allem, wenn Sie eine benutzerdefinierte Logik benötigen, aber ich würde folgende Möglichkeiten vorschlagen:

  1. Verwenden Sie eine generische Map-Funktion (Verlängert Dapper GridReader, das Ergebnis von QueryMultiple ist)

    public static class DapperExtension 
    { 
    public static IEnumerable<TFirst> Map<TFirst, TSecond, TKey> 
        (
        this SqlMapper.GridReader reader, 
        Func<TFirst, TKey> firstKey, 
        Func<TSecond, TKey> secondKey, 
        Action<TFirst, IEnumerable<TSecond>> addChildren 
        ) 
        { 
         var first = reader.Read<TFirst>().ToList(); 
    
         var childMap = reader.Read<TSecond>() 
              .GroupBy(secondKey) 
              .Where(grp => 
              { 
               if (
                Nullable.GetUnderlyingType(typeof(TKey)) != null 
                && grp.Key == null 
                ) 
                return false; 
               return true; 
              }) 
              .ToDictionary(g => g.Key, g => g.ToList()); 
    
    
         foreach (var item in first) 
         { 
          List<TSecond> children; 
    
          addChildren(item, childMap.TryGetValue(firstKey(item), out children) ? children : new List<TSecond>()); 
         } 
    
         return first; 
        } 
    } 
    

Für den Dapper Aufruf:

var supervisorGridReader = conn.QueryMultiple("StoredProc", ....) 

, die in dem GridReader Objekt führt, verlängert durch oben Map-Methode, so dass Sie zwei Sammlungen von SupervisorParent und Supervisor Klasse erhalten werden, als Teil der QueryMultiple,

Var result = supervisorGridReader.Map<SupervisorParent,Supervisor,string> 
           (
           ps => ps.SupervisorID, 
           cs => cs.ParentSupervisorID, 
           (ps,cs) => ps.ChildSupervisor = cs.ToList() 
           ); 

Hier result ist vom Typ IEnumerable<SupervisorParent>

Bitte beachten Sie hier Supervisor-Klassen-Schema folgende Verfahren werden

public class SupervisorParent 
    { 
     public string SupervisorID { get; set; } 
     public string ParentSupervisorID { get; set; } 
     public string Name { get; set; } 
     public string Location { get; set; } 
     public List<Supervisor> ChildSupervisor { get; set; } 
    } 

public class Supervisor 
     { 
      public string SupervisorID { get; set; } 
      public string ParentSupervisorID { get; set; } 
      public string Name { get; set; } 
      public string Location { get; set; } 
     } 

Dabei wird ChildSupervisor mit der Kartenfunktion gefüllt, wie in der Kartenfunktion gezeigt.

Sie es auch erreichen die expliziten Linq verwenden, da in jedem Fall, dass ich auch die Linq in der Map-Funktion verwenden die beiden Ergebnisse der QueryMultiple zu verschmelzen.

Explicit Linq wird wie folgt aussehen:

foreach(SupervisorParent parent in SupervisorParentList) 
{ 
    parent.ChildSupervisor = 
     SupervisorList.Where(child => 
     child.ParentSupervisorID = parent.SupervisorID 
} 
Verwandte Themen