2016-08-09 5 views
2

Ich bin versuchen, eine Abfrage zu tun, die die folgenden korrekt abbildet:Wie erstellt man eine Multi-Mapping-Abfrage in Dapper mit drei Ebenen Tiefe Mapping?

public class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int BId {get; set; } 
    public List<B> { get; set; } 
} 

public class B 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int CId { get; set; } 
    public int DId { get; set; } 
    public C C { get; set; } 
    public D D { get; set; } 
} 

public class C 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class D 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

Wie schreibe ich eine Abfrage, die mit einer Liste von Unternehmen B mit C und D gefüllt korrekt Einheit A abbildet?

Antwort

1

Sie möchten hier zwei Abfragen durchführen, um die Eins-zu-Viele-Natur von B auf A zu erfassen. Außerdem werden Ihre Bs wahrscheinlich einen Verweis auf A in der Abfrage benötigen.

var query1 = conn.Query<A>(select * from dbo.A) 

var query2 = conn.Query<B,C,D,B>("select * from dbo.B...join C...join 

D",(b,c,d)=>{ 



    b.C = c; 
     b.D = d; 

return b; 

     } 

Jetzt musst du sie miteinander verbinden. Ich benutze Linq Joins und Erweiterungen, um eine Menge davon zu automatisieren, aber das Wesentliche ist, Schleife über jeden 'A' und finden Sie die passenden 'B's von Abfrage 2. Wörterbücher und Listen möglicherweise schneller als' Where 'auch, so Sie kann eine Erweiterung schreiben, die die darunter liegende Schleife optimiert.

foreach(var a in query1){ 
a.Bs = query2.Where(w=>w.AId.Equals(a.Id)); 
} 

Beachten Sie, dass Reisen in die db reduzieren QueryMultiple durch die Verwendung mehrerer Cord-Sets zurück (sollte Ihr db-Unterstützung, die).

+0

Hum, ich werde das morgen versuchen. Nicht möglich, es in einer einzelnen Abfrage zu tun? – GustavoAndrade

+0

Sie könnten es in einer Abfrage tun und dann von a gruppieren. Ich mag es mehr mit zwei und keine vollständige Zuordnung zu A in Abfrage 2. Sie könnten auch einen Parameter namens WithDetails haben, der optional query2 zurückgibt. Sie haben also eine superschnelle Abfrage mit einer Tabelle (z. B. eine Listenseite) und eine Detailabfrage. – BlackjacketMack

+0

Ein letzter Kommentar ... Sie müssen wahrscheinlich nicht die vollständige query2.A zuordnen ... so lange wie query.B das Aid hat, können Sie es mit der Abfrage1.A.AId abgleichen. Ein kleiner Punkt, aber es würde Sie davor bewahren, diesen Join in Abfrage2 zu machen und würde die Anzahl der zurückgegebenen Spalten verringern ... beides gute Dinge. Ich werde meine Antwort aktualisieren, um das zu klären. – BlackjacketMack

0

Sie könnten wahrscheinlich in einer Hin- und Rückfahrt zur db mit Drapper (auf Dapper gebaut) erreichen.

Vorausgesetzt Sie haben eine Reihe von SQL-Abfragen, die mehrere Ergebnisse zurückgeben:

select * from [TableA]; 
select * from [TableB]; 
select * from [TableC]; 
select * from [TableD] 

... mit jedem Ergebnis zu den anderen in irgendeiner Form Kennung/Fremdschlüssel halten, könnten Sie wahrscheinlich ein Repository wie aufbauen derjenige unter:

public class Repository : IRepository 
{ 
    // IDbCommander is a Drapper construct. 
    private readonly IDbCommander _commander; 

    public Repository(IDbCommander commander) 
    { 
     _commander = commander; 
    } 

    public IEnumerable<A> RetrieveAll() 
    { 
     // execute the multiple queries and 
     // pass control to a mapping function. 
     return _commander.Query(Map.Results); 
    } 

    private static class Map 
    { 
     internal static Func<IEnumerable<A>, 
          IEnumerable<B>, 
          IEnumerable<C>, 
          IEnumerable<C>, 
          IEnumerable<A>> Results = (collectionA, collectionB, collectionC, collectionD) => 
     { 
      // map C and D to B based on their Id's 
      collectionB.C = collectionC.SingleOrDefault(c => c.Id == b.Id); 
      collectionB.D = collectionD.SingleOrDefault(d => d.Id == b.Id); 

      // now map B to A. 
      collectionA.B = collectionB.Where(b => b.Id == a.Id).ToList(); 
      return collectionA; 
     } 
    } 
} 

Beispiel aus dem Speicher eingegeben so Syntax ein wenig aus sein könnte, aber Sie den Kern erhalten.

Ich stimme mit BlackjacetMack überein, dass Sie eher eine Art von Seitenumbruch in den Ergebnissen haben sollten (auch in Drapper unterstützt).

Verwandte Themen