C# Oracle托管提供程序混合参数
我有一些代码看起来是这样的(我已经简化了它以关注这个问题,但代码完全如下,替换了敏感数据名称): 为了说明这个问题,“TargetGroupId”是12345,“PreviousGroupId”是67890 从这段代码中,我希望Id为12345的记录的LinkFromId更新为67890 但情况恰恰相反,Id为67890的记录的LinkFromId设置为12345 现在,要获得预期的行为很容易,请交换分配给每个参数的值C# Oracle托管提供程序混合参数,c#,oracle,C#,Oracle,我有一些代码看起来是这样的(我已经简化了它以关注这个问题,但代码完全如下,替换了敏感数据名称): 为了说明这个问题,“TargetGroupId”是12345,“PreviousGroupId”是67890 从这段代码中,我希望Id为12345的记录的LinkFromId更新为67890 但情况恰恰相反,Id为67890的记录的LinkFromId设置为12345 现在,要获得预期的行为很容易,请交换分配给每个参数的值 但问题仍然存在,为什么参数要与预期的参数进行交换?是的,我已经三次检查了查询
但问题仍然存在,为什么参数要与预期的参数进行交换?是的,我已经三次检查了查询是否与我认为的一样,参数是否正确传入(就像我没有意外地以相反的顺序命名查询中的参数或其他任何东西)。我遗漏了什么吗?请确保在执行命令对象之前,告诉它按名称绑定参数
cmd.BindByName=true;
如果你不这样做,它会按顺序绑定它们。如果它们是按照您引用它们的相反顺序添加的,则可以解释交换
我总是将该属性设置为
true
,因为替代项不可用。它应该是默认值,但这将是一个突破性的变化。幸运的是,这是特定于Oracle提供商的。是否设置cmd.BindByName=true代码>?我在这里看不到……我不知道这是一件事。我看到的例子没有这个。让我试试。是的,这就是诀窍。如果你想发布的答案,我很乐意给予信贷。非常感谢,这一次我真是太激动了。
private const string TargetIdParamName = "TargetId";
private const string LinkedGroupIdParamName = "LinkedGroupId";
private static readonly string UpdateLinkFromSql =
$@"UPDATE MyTableName
Set LinkFromId = :{LinkedGroupIdParamName}
WHERE Id = :{TargetIdParamName}";
using (var dbConn = GetConnection())
{
dbConn.Open();
using (var trans = dbConn.BeginTransaction())
{
try
{
var cmd = dbConn.CreateTransactedCommand(trans);
AddParameters(cmd);
cmd.CommandText = UpdateLinkFromSql;
cmd.Parameters[TargetIdParamName].Value = request.TargetGroupId;
cmd.Parameters[LinkedGroupIdParamName].Value = request.BreakPreviousLink ? DBNull.Value : (object) request.PreviousGroupId.Value;
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
throw;
}
}
}
private void AddParameters(OracleCommand cmd)
{
cmd.Parameters.Add(TargetIdParamName, OracleDbType.Long, ParameterDirection.Input);
cmd.Parameters.Add(LinkedGroupIdParamName, OracleDbType.Long, ParameterDirection.Input);
}
public static class DataAccessExtensions
{
public static OracleCommand CreateTransactedCommand(this OracleConnection source, OracleTransaction trans)
{
var cmd = source.CreateCommand();
cmd.Transaction = trans;
return cmd;
}
}