6

我想知道 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)

4

2 回答 2

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;

});

可能可以将其包装在扩展方法中,但没有想到任何聪明的方法。

于 2013-05-09T19:32:35.220 回答
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();

    }
}
于 2014-03-13T18:13:44.070 回答