web-dev-qa-db-fra.com

Exécuter la procédure stockée avec les paramètres dans Dapper

J'utilise Dapper (merci Sam , excellent projet.) Un micro ORM avec un DAL et, pour une raison quelconque, je ne suis pas en mesure d'exécuter des procédures stockées avec des paramètres d'entrée. 

Dans un exemple de service, j'ai le code suivant: 

public void GetSomething(int somethingId)
{
    IRepository<Something, SomethingEnum> repository = UnitOfWork.GetRepository<Something, SomethingEnum>();

    var param = new DynamicParameters();
    param.Add("@somethingId", dbType: DbType.Int32, value:somethingId, direction: ParameterDirection.Input);

    var result = repository.Exec<Something>(SomethingEnum.spMyStoredProcedure, param);

    ...

}

Lorsque l'exécution de la procédure stockée est déclenchée, une exception SqlException est émise, indiquant que je dois fournir l'élément 'quelquechose'

La procédure ou la fonction 'spMyStoredProcedure' attend le paramètre '@somethingId', qui n'a pas été fourni.

Mon DAL est similaire sur ce projet github de Pencroff.

Est-ce que j'ai râté quelque chose?

Update: Je passe actuellement le commandType via le SomethingEnum: 

 public class SomethingEnum : EnumBase<SomethingEnum, string>
 {
    public static readonly SomethingEnum spMyStoredProcedure = new SomethingEnum("spMyStoredProcedure", "[dbo].[spMyStoredProcedure]", CommandType.StoredProcedure);

    public SomethingEnum(string Name, string EnumValue, CommandType? cmdType): base(Name, EnumValue, cmdType)
    {
    }
}
11
antao

Vous devez lui indiquer le type de commande: assurez-vous qu'il y a un commandType: CommandType.StoredProcedure dans l'appel dapper. Sinon, il exécute simplement la commande text:

spMyStoredProcedure

(avec quelques paramètres inutilisés dans le contexte ambiant). Ceci est légal TSQL et tente d’appeler spMyStoredProcedure sans transmettre de paramètres - comme si vous mettiez spMyStoredProcedure dans SSMS et appuyez sur f5.

De plus, si vos paramètres sont fixes, je suggérerais simplement d’utiliser:

var param = new { somethingId };

ou même tout simplement en ligne complètement:

var result = repository.Exec<Something>(SomethingEnum.spMyStoredProcedure,
    new { somethingId }, commandType: CommandType.StoredProcedure);

(Remarque: si votre méthode Exec<T> ne gère que des procédures stockées, vous pouvez déplacer le nom interne commandType vers la méthode - ou vous pouvez en faire un paramètre facultatif dont la valeur par défaut est CommandType.StoredProcedure.)

25
Marc Gravell
var queryParameters = new DynamicParameters();
queryParameters.Add("@parameter1", valueOfparameter1);
queryParameters.Add("@parameter2", valueOfparameter2);

await db.QueryAsync<YourReturnType>(
    "{NameOfStoredProcedure}",
    queryParameters,
    commandType: CommandType.StoredProcedure)
3
Jay Shah

Comme c'était le meilleur résultat pour moi, mais en l'absence de réponses concernant ExecuteNonQuery avec des paramètres de valeur table, voici le code correspondant:

var queryParameters = new DynamicParameters();
queryParameters.Add("@Param0", datatable0.AsTableValuedParameter());
queryParameters.Add("@Param1", datatable1.AsTableValuedParameter());
var result = await ExecuteStoredProc("usp_InsertUpdateTest", queryParameters);

private async Task<Result<int>> ExecuteStoredProc(string sqlStatement, DynamicParameters parameters)
    {
        try
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                await conn.OpenAsync();
                var affectedRows = await conn.ExecuteAsync(
                    sql: sqlStatement,
                    param: parameters,
                    commandType: CommandType.StoredProcedure);
                return Result.Ok(affectedRows);
            }
        }
        catch (Exception e)
        {
            //do logging
            return Result.Fail<int>(e.Message);
        }
    }
0
ToDevAndBeyond

Vous devrez l'étendre pour prendre en charge les paramètres sortants et renvoyer les résultats, mais il contient la partie permettant de créer les paramètres dynamiques Dapper.

internal static bool ExecuteProc(string sql, List<SqlParameter> paramList = null)
{
    try
    {
        using (SqlConnection conn = new SqlConnection (GetConnectionString()))
        {                    
           DynamicParameters dp = new DynamicParameters();
           if(paramList != null)
               foreach (SqlParameter sp in paramList)
                   dp.Add(sp.ParameterName, sp.SqlValue, sp.DbType);
           conn.Open();
           return conn.Execute(sql, dp, commandType: CommandType.StoredProcedure) > 0;
        }
    }
    catch (Exception e)
    {
        //do logging
        return false;
    }

}

0
Lodlaiden