我可以将DynamicParameters与Template一起使用并在dapper中使用返回参数吗?

我目前正在处理的系统使用存储过程进行所有数据访问。 我现在正在研究Dapper(到目前为止它看起来很棒)但是我想知道我是否可以使用使用模板创建的DynamicParameters对象,但是将其中一个参数作为输出参数。 例如:

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

码:

 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("ID"); 

当前我收到错误,因为找不到密钥。 有没有办法获得ID输出参数而无需手动设置所有存储的procs参数?

通过快速调整, Add now 将替换模板中的值,允许:

 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("ID").IsEqualTo(7); } 

这够近吗? 您还可以使用ParameterDirection.ReturnValue ,它是预先存在的值或新值。 请注意,它不会直接更新回原始模板; 必须从DynamicParameters实例中获取该值(如图所示)。

当您使用DynamicParameters的构造函数指定模板对象时,您仍需要指定@ID是输出参数。 首先,通过模板,它将被设置为ParameterDirection.Input 。 添加后,它将被覆盖以获得更新的值,然后您可以通过参数名称获取值,如下所示:

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

除了我上面展示的内容之外,我能够使用它并使用您的类和代码。

编辑:正如评论中所讨论的,存储过程不接受比它声明的更多的参数。 因此,另一种方法是抛弃存储过程并使用一些内联SQL。 当您使用查询时,Dapper将忽略给定的任何未在SQL语句中指定的参数。 这是解决此问题的解决方法:

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

请注意, SCOPE_IDENTITY()返回小数,而不是int。

另一个我认为不理想的想法是修改Dapper代码并向DynamicParameters类添加Remove方法以删除不需要的参数。 这并不会为您节省太多,因为您仍然会花时间指定要删除所有参数以使存储过程满意。 如果您决定实现这一点,请记住在指定要从parameters字典中删除的键时该情况很重要。