Servicestack ORMLite查询多个

时间:2013-05-09 15:15:32

标签: servicestack ormlite-servicestack

我想知道ORMLite是否有像Dapper这样的QueryMultiple解决方案。

我的用例是获取分页结果。

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)

2 个答案:

答案 0 :(得分: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 :(得分:3)

你可以很容易地创建一些帮助OrmLite扩展(在v 3.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();

    }
}