Dapper.NET和具有多个结果集的存储过程


79

有什么方法可以将Dapper.NET与返回多个结果集的存储过程一起使用?

就我而言,第一个结果集是单行单列;如果是,0则调用成功,第二个结果集将包含实际的数据行/列。(如果它不为零,则会发生错误,并且不会提供第二个结果集)

有机会使用Dapper.NET处理吗?到目前为止,我只回过单曲0,但仅此而已。

更新:好的,只要结果集没有。2是单个实体:

Dapper.SqlMapper.GridReader reader = 
    _conn.QueryMultiple("sprocname", dynParams, 
    commandType: CommandType.StoredProcedure);

int status = reader.Read<int>().FirstOrDefault();
MyEntityType resultObj = reader.Read<MyEntityType>().FirstOrDefault();

现在,我还有另一个要求。

精致小巧的多映射(分裂从SQL Server返回到两个独立的实体单行)对于第二个结果集似乎不支持作为尚未(至少似乎没有成为过载.Read<T>,可以处理多重映射)。

如何将该行分为两个实体?


如果您需要在序列化后将单独的结果集合并在一起或“缝合在一起” ... dotnet代码中的集合,这是一个很好的帮助方法。 stackoverflow.com/questions/6379155/…–
granadaCoder

Answers:


69

您是否尝试过该QueryMultiple方法?它说应该:

执行一个返回多个结果集的命令,并依次访问每个结果集

您需要添加此using语句以启用QueryMultiple。

using Dapper; /* to add extended method QueryMultiple public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); */

27
可以从示例或更多详细信息的链接中受益。
Trevor.Screws

125

QueryMultiple支持处理多个结果集的能力。我们添加的唯一设计限制是完全禁用网格读取器的缓冲。这意味着整个API正在流式传输

在最简单的情况下,您可以使用:

var grid = connection.QueryMultiple("select 1 select 2");
grid.Read<int>().First().IsEqualTo(1);
grid.Read<int>().First().IsEqualTo(2);

在稍微复杂一些的情况下,您可以执行以下疯狂操作:

var p = new DynamicParameters();
p.Add("a", 11);
p.Add("r", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

connection.Execute(@"create proc #spEcho
@a int
as 
begin

select @a Id, 'ping' Name, 1 Id, 'pong1' Name
select @a Id, 'ping' Name, 2 Id, 'pong2' Name
return @a
end");

var grid = connection.QueryMultiple("#spEcho", p, 
                                     commandType: CommandType.StoredProcedure);

var result1 = grid.Read<dynamic, dynamic, Tuple<dynamic, dynamic>>(
                  (a, b) => Tuple.Create((object)a, (object)b)).ToList();
var result2 = grid.Read<dynamic, dynamic, Tuple<dynamic, dynamic>>(
                  (a, b) => Tuple.Create((object)a, (object)b)).ToList();

((int)(result1[0].Item1.Id)).IsEqualTo(11);
((int)(result1[0].Item2.Id)).IsEqualTo(1);

((int)(result2[0].Item1.Id)).IsEqualTo(11);
((int)(result2[0].Item2.Id)).IsEqualTo(2);

p.Get<int>("r").IsEqualTo(11);

您需要添加此using语句以启用QueryMultiple。

using Dapper; /* to add extended method QueryMultiple public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); */

23
将来的读者注意:QueryMultiple不支持Oracle,或者说Oracle不支持QueryMultiple。见stackoverflow.com/questions/1062569/...
查尔斯·伯恩斯

21
困扰于使用Oracle的消息。
Pure.Krome

2
这很棒!有什么需要注意的警告吗?还是将数据作为一次往返获取?
scgough

这是否支持多线程以允许从多读取器并行读取?
barakcaf

您是否必须启用MultipleActiveResultSets才能执行此操作?要么?也许我只是不明白什么是MultipleActiveResultSets用于:)
mslot

22

多个结果集。

var reader = conn.QueryMultiple("ProductSearch", param: new { CategoryID = 1, SubCategoryID = "", PageNumber = 1 }, commandType: CommandType.StoredProcedure);
var CategoryOneList = reader.Read<CategoryOne>().ToList();
var CategoryTwoList = reader.Read<CategoryTwo>().ToList();

您需要添加此using语句以启用QueryMultiple。

using Dapper; /* to add extended method QueryMultiple public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); */

存储过程:

CREATE PROCEDURE [dbo].[ProductSearch]
    @CategoryID as varchar(20),
    @SubCategoryID as varchar(20),
    @PageNumber as varchar(20)
AS
BEGIN
    SELECT * FROM ProductTbl
    SELECT * FROM ProductTbl
END

1
Oracle确实支持QueryMultiple或QueryMultipleAsync
Umar Topia '17

1
但是,它又如何知道要映射的类别呢?第一次调用Read pull是从第一个返回的结果集中进行吗?
WhiteleyJ

1
@Yojin分别是
阿伦·普拉萨德

1
如果您需要“合并”或“缝合”单独的收藏夹,这是一个很好的帮助方法。 stackoverflow.com/questions/6379155/…–
granadaCoder
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.