Dapper.NET и хранимая процедура с несколькими наборами результатов

Есть ли способ использовать 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();

Теперь у меня есть еще одно требование.

Множественное отображение Dapper (разделение одной строки, возвращаемой из SQL Server, на две отдельные сущности) для этого второго набора результатов, похоже, пока не поддерживается (по крайней мере, похоже, что нет перегрузки .Read<T>, которая может обрабатывать множественное отображение).

Как я могу разбить эту строку на две части?


person marc_s    schedule 11.06.2011    source источник
comment
Если вам нужно объединить или сшить отдельные наборы результатов ... или коллекции в коде dotnet после сериализации, вот отличный вспомогательный метод. stackoverflow.com/questions/ 6379155 /   -  person granadaCoder    schedule 13.11.2018


Ответы (3)


Вы пробовали метод 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); */
person Andomar    schedule 11.06.2011
comment
Для этого ответа было бы полезно привести пример или ссылку с более подробной информацией. - person Trevor.Screws; 14.11.2017

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); */
person Sam Saffron    schedule 14.06.2011
comment
Примечание для будущих читателей: QueryMultiple не поддерживает Oracle, точнее, Oracle не поддерживает QueryMultiple. См. stackoverflow.com/questions/1062569/ - person Charles Burns; 13.02.2014
comment
Приветствую вас за то, что вы застряли в использовании Oracle. - person Pure.Krome; 06.04.2016
comment
отлично! есть ли предостережения по этому поводу? Также извлекаются ли данные за один рейс туда и обратно? - person scgough; 21.10.2016
comment
Поддерживает ли это многопоточность для параллельного чтения с мульти-ридера? - person barakcaf; 07.03.2018
comment
Вам нужно включить MultipleActiveResultSets для этого? Или? Может, я просто не понимаю, для чего используется MultipleActiveResultSets :) - person mslot; 07.08.2019

Множественный набор результатов.

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
person Arun Prasad E S    schedule 10.04.2017
comment
Oracle поддерживает QueryMultiple или QueryMultipleAsync - person Umar Topia; 02.08.2017
comment
Но как он узнает, в какую категорию его сопоставить? При первом вызове Read извлекается ли из первого возвращенного набора результатов? - person WhiteleyJ; 15.08.2018
comment
@Yojin Да, соответственно - person Arun Prasad E S; 16.10.2018
comment
Если вам нужно объединить или сшить отдельные коллекции, вот отличный вспомогательный метод. stackoverflow.com/questions/ 6379155 / - person granadaCoder; 13.11.2018
comment
Какие изменения зависят от того, включаете ли вы .ToList()? Я вижу, что и вы, и @Sam Saffron сделали это в своих примерах кода. Влияет ли это на количество циклов приема-передачи или объем возвращаемых данных? - person mft25; 07.12.2020
comment
У меня это не сработало. Я реализовал dapper с .net core 5.0. - person Mustafa Tığ; 19.03.2021