Dapper.NET і зберігається proc з декількома наборами результатів


80

Чи є спосіб використовувати 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>яке може впоратися мульти-відображення).

Як я можу розділити цей рядок на дві сутності?


Якщо вам потрібно об’єднати або «з’єднати» окремі набори результатів ... aka колекції в коді dotnet після серіалізації, ось чудовий допоміжний метод. stackoverflow.com/questions/6379155 / ...
granadaCoder

Відповіді:


69

Ви пробували QueryMultipleметод? Там сказано, що слід:

Виконайте команду, яка повертає кілька наборів результатів, і отримуйте доступ до кожного по черзі

Вам потрібно буде додати це за допомогою оператора, щоб увімкнути 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
Ця відповідь допоможе на прикладі чи посиланні з більш детальною інформацією.
Тревор. Гвинти

126

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);

Вам потрібно буде додати це за допомогою оператора, щоб увімкнути 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 07.03.18

Чи потрібно вмикати MultipleActiveResultSets для цього? Або? Можливо, я просто не розумію, для чого використовується MultipleActiveResultSets :)
mslot

24

Множинні результати.

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();

Вам потрібно буде додати це за допомогою оператора, щоб увімкнути 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

1
Але звідки воно знає, до якої категорії його також відобразити? Чи перший раз, коли ви викликаєте Read, витягується з першого повернутого набору результатів?
WhiteleyJ

1
@Yojin Так, відповідно
Arun Prasad ES

1
Якщо вам потрібно «об’єднати» або «з’єднати» окремі колекції, ось чудовий допоміжний метод. stackoverflow.com/questions/6379155 / ...
granadaCoder

Які зміни залежать від того, включаєте ви чи ні .ToList()? Я бачу, що і ви, і @Sam Saffron зробили це у своїх зразках коду. Чи це впливає на кількість зворотних поїздок або кількість повернутих даних?
mft25,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.