2013-05-09 69 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(); 

    } 
}