在Dapper中使用/参数执行存储过程

时间:2014-02-06 09:15:02

标签: c# sql stored-procedures data-access-layer dapper

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

在示例服务中,我有以下代码:

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

    ...

}

当触发执行存储过程时,抛出SqlException,说明我需要提供'somethingId'

  

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

根据Pencroff的这个github项目,我的DAL类似。

我在这里错过了什么吗?

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

 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)
    {
    }
}

4 个答案:

答案 0 :(得分:29)

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

spMyStoredProcedure

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

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

var param = new { somethingId };

甚至只是完全内联:

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

(注意:如果您的Exec<T>方法只处理存储过程,您可以将commandType内部移动到方法中 - 或者您可以将其设为默认为CommandType.StoredProcedure的可选参数)

答案 1 :(得分:4)

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

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

答案 2 :(得分:1)

因为这对我来说是最好的结果,但是没有使用表值参数处理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<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);
        }
    }

答案 3 :(得分:0)

您需要扩展它以支持出站参数和返回结果,但它包含用于创建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;
    }

}