2013-05-09 14 views
5

Ich frage mich, ob ORMLite eine QueryMultiple Lösung wie Dapper hatte.Servicestack ORMLite Query Multiple

Mein Anwendungsfall besteht darin, seitenweise Ergebnisse zu erhalten.

return new { 
    Posts = conn.Select<Post>(q => q.Where(p => p.Tag == "Chris").Limit(20, 10)) 
    TotalPosts = conn.Count<Post>(q.Where(p => p.Tag == "Chris")) 
}; 

Ich habe auch ein paar andere Fälle, in denen ich einige andere Statistiken zusätzlich zu einer Hauptabfrage bin Berechnung und ich bin daran interessiert, mehrere Rundreisen zu vermeiden.

(Wahrscheinlich nicht verwandten, aber ich bin mit PostgreSQL)

+0

Haben Sie eine Lösung für diese finden? – kaptan

Antwort

4

Sie wahrscheinlich so etwas wie dies tun können:

var bothThings = db.Exec(cmd => { 

    cmd.CommandText = @" 
     select * from TableA 
     select * from TableB"; 

    var both = new BothAandB(); 

    using (var reader = cmd.ExecuteReader()) 
    { 
     both.a = reader.ConvertToList<A>(); 
     reader.NextResult(); 
     both.b = reader.ConvertToList<B>(); 
    } 

    return both; 

}); 

Es könnte möglich sein, dies in eine Erweiterungsmethode einpacken, aber nichts gescheites kommt mir in den Sinn.

+1

Dies wird in der aktuellen Implementierung nicht funktionieren. 'ConvertToList' wendet intern ein' using (reader) 'an, das den Leser beim Ablegen schließt, wodurch verhindert wird, dass' NextResult() 'zugänglich ist. –

3

Sie können ziemlich leicht Hilfs Ormlite-Erweiterungen (funktioniert in v 3.9.55.0) erstellen, die den Leser nicht umschließt. Es ist ziemlich einfach, da die Methoden, die Sie benötigen, öffentlich sind. Hier ist, wie ich es gemacht habe.

public static class MultiResultReaderOrmLiteExtensions 
{ 
    public static IList CustomConvertToList<T>(this IDataReader dataReader) 
    { 
     var modelDef = ModelDefinition<T>.Definition; 
     var type = typeof (T); 
     var fieldDefs = modelDef.AllFieldDefinitionsArray; 
     var listInstance = typeof(List<>).MakeGenericType(type).CreateInstance(); 
     var to = (IList)listInstance; 
     var indexCache = dataReader.GetIndexFieldsCache(modelDef); 
     while (dataReader.Read()) 
     { 
      var row = type.CreateInstance(); 
      row.PopulateWithSqlReader(dataReader, fieldDefs, indexCache); 
      to.Add(row); 
     } 
     return to; 
    } 

    public static Dictionary<string, int> GetIndexFieldsCache(this IDataReader reader, 
     ModelDefinition modelDefinition = null) 
    { 
     var cache = new Dictionary<string, int>(); 
     if (modelDefinition != null) 
     { 
      foreach (var field in modelDefinition.IgnoredFieldDefinitions) 
      { 
       cache[field.FieldName] = -1; 
      } 
     } 
     for (var i = 0; i < reader.FieldCount; i++) 
     { 
      cache[reader.GetName(i)] = i; 
     } 
     return cache; 
    } 
} 

Dann können Sie wie in etwa so nennen:

using (var db = _connectionFactory.OpenDbConnection()) 
{ 
    var cmd = db.api_GetSprocWithMultResults(id); 
    using (IDataReader reader = cmd.DbCommand.ExecuteReader()) 
    { 
     meta = reader.CustomConvertToList<Element_Media_Meta>().Cast<Element_Media_Meta>().ToList(); 
     reader.NextResult(); 
     queues = reader.CustomConvertToList<Element_Media_ProcessQueue>().Cast<Element_Media_ProcessQueue>().ToList(); 

    } 
}