2017-04-03 4 views
0

Ich habe eine Basis-Repository mit einem generischen Methode Get Daten zurück mit Dapper wieGenerisches QueryMultiple mit Dapper

public T Get<T>(Func<IDbConnection, T> query) 
    { 
     using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString)) 
     { 
      return query.Invoke(db); 
     } 
    } 

aber jetzt habe ich die Notwendigkeit, mehrere Daten zurückzukehren. Die DAL-Abfrage ist wie folgt:

var multi = db.QueryMultiple(getCarDataSp , new { CustomerID = customerId, Year = year }, 
           commandType: CommandType.StoredProcedure)); 

var cars = multi.Read<CarDTO>(); 
var options = multi.Read<CarOptionDTO>(); 

//wire the options to the cars 
foreach(var car in cars){ 
    var carOptions = options.Where(w=>w.Car.CarID == car.CarID);  //I would override Equals in general so you can write w.Car.Equals(car)...do this on a common DataModel class 
    car.Options = carOptions.ToList(); 
} 

es möglich wäre, eine generische GetMultiple in meinem BaseRepository zu haben oder es eine Frage der Einwickeln des bekommen mehr in meiner Get-Methode und dann Autos und Optionen dort eigenen getrennt sein Anrufe bekommen?

+0

Als Ihr Anwendungsfälle bekommen komplexer, werden Lösungen weniger allgemein verwendbar. Ich empfehle nicht, sowas in eine BaseRepository-Klasse zu schreiben. Wenn Sie das tun, benötigen Sie mehrere Anwendungsfälle, um es korrekt zu erstellen. –

+0

Yeah war ähnlich. Im Moment habe ich die Implementierung für diese Methode getrennt und nicht das Base Repository und denke, dass es meinen Bedürfnissen entspricht. Prost –

+0

Welchen Wert fügt dieser Code hinzu? Nur die Wahl der Verbindungszeichenfolge. Und es reduziert die gesamte Dapper-Oberfläche auf einen Query-Aufruf. Es ist schlau, aber ich denke nicht, dass es eine gute Idee ist. – bbsimonbb

Antwort

1

Sie könnten so etwas tun, das ein Tupel zurückgibt, das IEnumerables von jedem Typ enthält, nach dem Sie suchen.

Im Basis Repository

(es ist im Grunde ein Bündel von Überlastungen ... können Sie mehr Überlastungen hinzufügen, wenn Sie mehr Arten haben).

public Tuple<IEnumerable<T1>, IEnumerable<T2>> GetMultiple<T1, T2>(string sql, object parameters, 
             Func<GridReader, IEnumerable<T1>> func1, 
             Func<GridReader, IEnumerable<T2>> func2) 
     { 
      var objs = getMultiple(sql, parameters, func1, func2); 
      return Tuple.Create(objs[0] as IEnumerable<T1>, objs[1] as IEnumerable<T2>); 
     } 

     public Tuple<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>> GetMultiple<T1, T2, T3>(string sql, object parameters, 
             Func<GridReader, IEnumerable<T1>> func1, 
             Func<GridReader, IEnumerable<T2>> func2, 
             Func<GridReader, IEnumerable<T3>> func3) 
     { 
      var objs = getMultiple(sql, parameters, func1, func2, func3); 
      return Tuple.Create(objs[0] as IEnumerable<T1>, objs[1] as IEnumerable<T2>, objs[2] as IEnumerable<T3>); 
     } 

     private List<object> getMultiple(string sql, object parameters,params Func<GridReader,object>[] readerFuncs) 
     { 
      var returnResults = new List<object>(); 
      using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString)) 
      { 
       var gridReader = db.QueryMultiple(sql, parameters); 

       foreach(var readerFunc in readerFuncs) 
       { 
        var obj = readerFunc(gridReader); 
        returnResults.Add(obj); 
       } 
      } 

      return returnResults; 
     } 

In Abgeleitet Repository

(ziemlich sauber und was noch wichtiger ist, getippt!)

public class Foo { } 

     public class Bar { } 

     public void sample() 
     { 
      var sql = "select * from Foo; select * from Bar"; 
      var foosAndBars = this.GetMultiple(sql, new { param = "baz" }, gr => gr.Read<Foo>(), gr => gr.Read<Bar>()); 
      var foos = foosAndBars.Item1; 
      var bars = foosAndBars.Item2; 
     } 
+0

Ich werde es versuchen. Ich hatte eigentlich geglaubt, Tuple wäre noch weit weg, aber wir haben nicht weiter daran gedacht, es korrekt zurückzugeben. Was würden Sie empfehlen, zwei generische Typen zu benennen? Ich habe T und U schon früher in Büchern pr T und TU gesehen. Raten Sie T1 und T2 ist in Ordnung, nur wundernd, gibt es eine Standardkonvention –

+0

Ich denke, dass die adretten Leute T1, T2 verwenden ... Sie könnten das bis zu 8 mit Generika überladen, wobei das Tupel die Begrenzung ist. – BlackjacketMack

+0

Was ist, wenn ich nicht weiß, wie viele Ergebnissätze da wären? – Manoj