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

mar*_*c_s 73 sql-server stored-procedures multiple-resultsets dapper

有没有办法使用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();
Run Code Online (Sandbox Code Playgroud)

现在,我还有另一项要求.

对于第二个结果集,Dapper的多映射(将从SQL Server返回的单行拆分为两个独立的实体)似乎尚未得到支持(至少似乎没有.Read<T>可以处理的重载)多映射).

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

Sam*_*ron 117

QueryMultiple支持处理多个结果集的能力.我们添加的唯一设计限制是完全禁用网格阅读器的缓冲.这意味着整个API都是流媒体.

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

var grid = connection.QueryMultiple("select 1 select 2");
grid.Read<int>().First().IsEqualTo(1);
grid.Read<int>().First().IsEqualTo(2);
Run Code Online (Sandbox Code Playgroud)

在稍微复杂的情况下,你可以做这样的疯狂的事情:

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);
Run Code Online (Sandbox Code Playgroud)

您需要添加此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); */
Run Code Online (Sandbox Code Playgroud)

  • 请注意未来的读者:QueryMultiple不支持Oracle,或者更确切地说,Oracle不支持QueryMultiple.请参阅http://stackoverflow.com/questions/1062569/batch-multiple-select-statements-when-calling-oracle-from-ado-net/1064692#1064692 (22认同)
  • 陷入使用Oracle的困境. (15认同)
  • 这很棒!有什么需要注意的吗?还是将数据作为一次往返检索? (2认同)

And*_*mar 67

你试过这个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); */
Run Code Online (Sandbox Code Playgroud)

  • 这个答案将受益于一个示例或更详细的链接. (22认同)

Aru*_*E S 14

多个结果集.

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();
Run Code Online (Sandbox Code Playgroud)

您需要添加此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); */
Run Code Online (Sandbox Code Playgroud)

存储过程:

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
Run Code Online (Sandbox Code Playgroud)

  • Oracle 确实支持 QueryMultiple 或 QueryMultipleAsync (2认同)