我目前正在处理的系统使用存储过程进行所有数据访问。我现在正在研究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<int>("ID");
当前我收到错误,因为找不到密钥。有没有办法获得ID输出参数而无需手动设置所有存储的procs参数?
答案 0 :(得分:7)
通过快速调整,Add
现在替换模板中的值,允许:
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);
}
那足够接近吗?您还可以使用预先存在的值或新值的ParameterDirection.ReturnValue
。请注意,不会直接更新回原始模板;必须从DynamicParameters
实例中获取该值(如图所示)。
答案 1 :(得分:2)
当您使用DynamicParameters
的构造函数指定模板对象时,您仍需要指定@ID
是输出参数。首先,通过模板,它将设置为ParameterDirection.Input
。添加后,它将被覆盖以获得更新的值,然后您可以通过参数名称获取值,如下所示:
procParams.Add("@ID", dbType: DbType.Int32, direction: ParameterDirection.Output);
// ... execute ...
person.ID = procParams.Get<int>("@ID");
除了上面显示的内容之外,我能够使用它并使用你的类和代码。
编辑:正如评论中所讨论的那样,存储过程不接受比声明的更多的参数。因此,另一种方法是抛弃存储过程并使用一些内联SQL。当您使用查询时,Dapper将忽略给定的任何未在SQL语句中指定的参数。这是一个解决这个问题的解决办法:
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;
请注意SCOPE_IDENTITY()
返回小数,而不是int。
我认为另一个不太理想的想法是修改Dapper代码并向Remove
类添加DynamicParameters
方法以删除不需要的参数。这并不会为您节省太多,因为您仍然会花时间指定要删除所有参数以使存储过程满意。如果您决定实现这一点,请记住在指定要从parameters
字典中删除的密钥时该情况很重要。