Puis-je utiliser DynamicParameters with Template et avoir un paramètre de retour dans dapper?

.net c# dapper

Question

Le système sur lequel je travaille actuellement utilise des procédures stockées pour tous les accès aux données. Je suis en train de regarder Dapper pour le moment (jusqu'à présent, ça a l'air génial) mais je me demandais si je pouvais utiliser un objet DynamicParameters créé en utilisant un Template mais faire de l'un des paramètres un paramètre de sortie. Par exemple:

SP:

CREATE PROCEDURE InsertPerson
  @ID int Output,
  @Name varchar(100),
  @DOB DateTime2
AS
--INSERT STATEMENT

SET @ID = SCOPE_IDENTITY()

POCO:

internal class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public DateTime DOB { get; set; }
}

Code:

var procParams = new DynamicParameters(person);
connection.Execute("InsertPerson", procParams, commandType: CommandType.StoredProcedure);

// This is where i'm having the issue, can it be done?
person.ID = procParams.Get<int>("ID");

Current Je reçois une erreur car la clé n'a pas été trouvée. Existe-t-il un moyen d'obtenir le paramètre de sortie de l'ID sans configurer manuellement tous les paramètres de processus stockés?

Réponse acceptée

Avec un réglage rapide, Add remplace désormais la valeur d'un modèle, permettant:

public void TestProcWithOutParameter()
{
    connection.Execute(
        @"CREATE PROCEDURE #TestProcWithOutParameter
@ID int output,
@Foo varchar(100),
@Bar int
AS
SET @ID = @Bar + LEN(@Foo)");
    var obj = new
    { // this could be a Person instance etc
        ID = 0,
        Foo = "abc",
        Bar = 4
    };
    var args = new DynamicParameters(obj);
    args.Add("ID", 0, direction: ParameterDirection.Output);
    connection.Execute("#TestProcWithOutParameter", args,
                 commandType: CommandType.StoredProcedure);
    args.Get<int>("ID").IsEqualTo(7);
}

Est-ce assez proche? Vous pouvez également utiliser ParameterDirection.ReturnValue , d'une valeur préexistante ou d'une nouvelle valeur. Notez qu'il ne met pas à jour directement dans le modèle d'origine; la valeur doit être extraite de l'instance DynamicParameters (comme indiqué).


Réponse populaire

Lorsque vous utilisez le constructeur de DynamicParameters pour spécifier un objet modèle, vous devez toujours spécifier que @ID est un paramètre de sortie. Au début, via le modèle, il sera défini sur ParameterDirection.Input . Une fois que vous l'ajoutez, il sera remplacé par les valeurs mises à jour, vous pourrez alors obtenir la valeur par le nom du paramètre comme suit:

procParams.Add("@ID", dbType: DbType.Int32, direction: ParameterDirection.Output);
// ... execute ...
person.ID = procParams.Get<int>("@ID");

J'ai pu faire fonctionner ce logiciel et utiliser vos classes et votre code, en plus de ce que j'ai montré ci-dessus.

EDIT: comme indiqué dans les commentaires, la procédure stockée n'accepte pas plus d'arguments que ce qu'elle a déclaré. Ainsi, une autre approche consiste à abandonner la procédure stockée et à recourir à du SQL en ligne. Lorsque vous utilisez une requête, Dapper ignore tous les paramètres qui ne lui sont pas spécifiés dans l'instruction SQL. Ceci est une solution pour résoudre ce problème:

string sql = "INSERT INTO Person (Name, DOB) VALUES (@Name, @DOB) SELECT SCOPE_IDENTITY()";
decimal id = conn.Query<decimal>(sql, procParams).First();
person.ID = (int)id;

Notez que SCOPE_IDENTITY() renvoie une décimale, pas un int.

Une autre idée, qui ne me semble pas idéale, consiste à modifier le code Dapper et à ajouter une méthode Remove à la classe DynamicParameters pour supprimer les paramètres indésirables. Cela ne vous économise pas beaucoup, car vous passerez encore du temps à spécifier les paramètres à supprimer pour que la procédure stockée soit satisfaite. Si vous décidez de l'implémenter, rappelez-vous que cette affaire est importante lorsque vous spécifiez la clé à supprimer du dictionnaire de parameters .




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi