2013-05-09 102 views
5

我想知道ORMLite是否有像Dapper這樣的QueryMultiple解決方案。Servicestack ORMLite查詢多個

我的用例是獲取分頁結果。

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

我也有在那裏我計算除了主查詢一些其他統計資料其他一些情況下,我希望避免多次往返。

(也許無關,但我使用PostgreSQL)

+0

你找到了一個解決方案? – kaptan 2014-10-30 18:25:58

回答

4

你也許可以做這樣的事情:

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; 

}); 

可能可以在一個擴展方法來包裝這件事,但沒有聰明想起來了。

+1

這實際上不會在當前的實施中起作用。 'ConvertToList'在內部應用了一個'using(reader)',它在處理時關閉閱讀器,防止可以訪問'NextResult()'。 – 2013-11-01 15:07:24

3

您可以很容易地創建一些幫助OrmLite擴展(在V3.9.55.0中工作),不會包裝讀者。這很容易,因爲你需要的方法是公開的。這是我如何做到的。

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

然後就可以調用像這樣的事情:

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

    } 
}