在Dapper中执行带有参数的存储过程

我正在使用Dapper (感谢Sam ,很棒的项目。)带有DAL的微型ORM,由于某种原因,我无法使用输入参数执行存储过程。

在某种服务中,我有这样的事情:

public void GetSomething(int somethingId) { IRepository repository = UnitOfWork.GetRepository(); var param = new DynamicParameters(); param.Add("@somethingId", dbType: DbType.Int32, value:somethingId, direction: ParameterDirection.Input); var result = repository.Exec(SomethingEnum.spMyStoredProcedure, param); ... } 

当存储过程的执行发生时,抛出SqlException声明我需要提供’somethingId’

过程或函数’spMyStoredProcedure’需要参数’@somethingId’,这是未提供的。

我的DAL类似于Pencroff的这个github项目。

我在这里错过了什么吗?

更新:我实际上是通过SomethingEnum传递commandType:

  public class SomethingEnum : EnumBase { public static readonly SomethingEnum spMyStoredProcedure = new SomethingEnum("spMyStoredProcedure", "[dbo].[spMyStoredProcedure]", CommandType.StoredProcedure); public SomethingEnum(string Name, string EnumValue, CommandType? cmdType): base(Name, EnumValue, cmdType) { } } 

你需要告诉它命令类型:确保在dapper调用中有一个commandType: CommandType.StoredProcedure 。 否则,它只是执行文本命令:

 spMyStoredProcedure 

(在环境上下文中有一些未使用的参数)。 这是合法的TSQL,并尝试在不传递参数的情况下调用spMyStoredProcedure – 就像将spMyStoredProcedure放入SSMS并按f5一样

此外,如果你的参数是固定的,我实际上建议只使用:

 var param = new { somethingId }; 

甚至只是完全内联它:

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

(注意:如果你的Exec方法只处理存储过程,你可以将commandType内部移动到方法中 – 或者你可以使它成为一个默认为CommandType.StoredProcedure的可选参数)

 var queryParameters = new DynamicParameters(); queryParameters.Add("@parameter1", valueOfparameter1); queryParameters.Add("@parameter2", valueOfparameter2); await db.QueryAsync( "{NameOfStoredProcedure}", queryParameters, commandType: CommandType.StoredProcedure) 

您需要扩展它以支持出站参数和返回结果,但它包含用于创建Dapper动态参数的部分。

 internal static bool ExecuteProc(string sql, List 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; } 

}

因为这对我来说是最好的结果,但是没有用表值参数处理ExecuteNonQuery的答案,这里是代码:

 var queryParameters = new DynamicParameters(); queryParameters.Add("@Param0", datatable0.AsTableValuedParameter()); queryParameters.Add("@Param1", datatable1.AsTableValuedParameter()); var result = await ExecuteStoredProc("usp_InsertUpdateTest", queryParameters); private async Task> 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(e.Message); } }