2016-03-29 17 views
0

Düz bir veriyi dapper kullanarak hiyerarşik bir şekle dönüştürmeyi severim. aşağıdaki gibiDüz verileri hiyerarşik bir şekilde Dapper C kullanarak dönüştürün #

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; } 
    } 

Ben dapper yoluyla bunu başarmak için çalıştım:

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

aşağıdaki sınıf biçime alınan verileri dönüştürmek için seversiniz: Prosedür aşağıdaki sınıf doldurmak için bana verileri döndürür

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(); 

İstediğiniz sonuca ulaşmak için bana yol gösterebilir misiniz? Belirli Supervisor collection size bu bir Parent Supervisor olacak olan bir List of Supervisor istiyoruz 1 to n complex mapping olduğu yerde

Teşekkür Sid gerekenler

cevap

0

bir sonucudur. Orada kutu mekanizmasının hiçbir dışarı Özel bir mantık gerekebilir, özellikle, ama şu yöntemler önermek istiyorum:

  1. bir Genel Harita işlevini kullanın

    (QueryMultiple sonucudur Zarif GridReader, genişletir)

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

    GridReader nesne ile sonuçlanır, uzatılan: Zarif çağrısı için

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; 
    } 
} 
Harita yöntemiyle yukarıda, sen QueryMultiple bir parçası olarak,

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

resultSupervisorParent iki koleksiyon ve Supervisor sınıf alacak böylece tiptedir IEnumerable<SupervisorParent>

Danışman sınıfları şemada

aşağıdaki olacak burada unutmayın
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; } 
     } 

ChildSupervisor, Harita işlevinde gösterildiği gibi Harita işleviyle doldurulur. her durumda ben QueryMultiple iki sonuçlarını birleştirmek için çok Harita fonksiyonunda Linq kullanıyorum beri

Ayrıca, açık Linq kullanarak bunu başarmak.

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

Açık Linq benzeyecek