102 votes

Dapper.NET et procédures stockées avec plusieurs ensembles de résultats

Y a-t-il un moyen d'utiliser Dapper.NET avec des procédures stockées qui renvoient plusieurs ensembles de résultats ?

Dans mon cas, le premier ensemble de résultats est une seule ligne avec une seule colonne ; si c'est 0, alors l'appel a été réussi et le deuxième ensemble de résultats contiendra les lignes/colonnes de données. (et s'il était différent de zéro, une erreur s'est produite et aucun deuxième ensemble de résultats ne sera fourni)

Est-il possible de gérer cela avec Dapper.NET ? Jusqu'à présent, je reçois toujours cette valeur unique 0 - mais rien d'autre.

Mise à jour : D'accord, ça fonctionne bien - tant que le deuxième ensemble de résultats est une seule entité :

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

int statut = reader.Read().FirstOrDefault();
MyEntityType objResult = reader.Read().FirstOrDefault();

Maintenant, j'ai encore un autre exigence.

Le multi-mapping de Dapper (divisant une seule ligne renvoyée par SQL Server en deux entités distinctes) pour ce deuxième ensemble de résultats ne semble pas être pris en charge à ce jour (du moins, il ne semble pas y avoir de surcharge de .Read qui peut gérer le multi-mapping).

Comment puis-je diviser cette ligne en deux entités ?

146voto

Sam Saffron Points 56236

QueryMultiple prend en charge la capacité de traiter plusieurs ensembles de résultats. La seule restriction de conception que nous avons ajoutée était de désactiver complètement le buffering pour le lecteur de grille. Cela signifie que toute l'API est en streaming.

Dans le cas le plus simple, vous pouvez utiliser :

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

Dans le cas légèrement plus sophistiqué, vous pouvez faire des trucs fous comme ceci :

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>(
                  (a, b) => Tuple.Create((object)a, (object)b)).ToList();
var result2 = grid.Read>(
                  (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("r").IsEqualTo(11);

Vous devrez ajouter cette instruction using pour activer QueryMultiple.

using Dapper; /* pour ajouter la méthode étendue QueryMultiple public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); */

79voto

Andomar Points 115404

Avez-vous essayé la méthode QueryMultiple? Il dit que cela devrait:

Exécuter une commande qui retourne plusieurs ensembles de résultats, et y accéder un par un

Vous devrez ajouter cette instruction using pour activer QueryMultiple.

using Dapper; /* pour ajouter la méthode étendue QueryMultiple public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); */

44voto

Arun Prasad E S Points 3375

Résultat multiple.

var reader = conn.QueryMultiple("ProductSearch", 
                  param: new { CategoryID = 1 }, 
                  commandType: CommandType.StoredProcedure);
var ProductListOne = reader.Read().ToList();
var ProductListTwo = reader.Read().ToList();

Vous devrez ajouter cette instruction using pour activer QueryMultiple.

using Dapper; 
/* Pour ajouter la méthode étendue QueryMultiple 
   public static GridReader QueryMultiple(
          this IDbConnection cnn, 
          string sql, 
          object param = null, 
          IDbTransaction transaction = null, 
          int? commandTimeout = null, 
          CommandType? commandType = null); 
*/

Procédure stockée:

CREATE PROCEDURE [dbo].[ProductSearch]
    @CategoryID as int
AS
BEGIN
    SELECT * FROM ProductTbl
    SELECT * FROM ProductTbl
END

0voto

pajarnas Points 351

Pour moi, il manquait une colonne dans ma table de base de données, l'une de mes requêtes génère une exception dans QueryMulitpleAsync() en raison de cette colonne manquante.

Je suggérerai de trouver celle qui vous bloque, puis de comparer la colonne de la base de données et votre chaîne de requête brute.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X