【问题标题】:ObjectContext.ExecuteStoreCommand doesn't recognise parameterObjectContext.ExecuteStoreCommand 无法识别参数
【发布时间】:2013-08-09 22:30:09
【问题描述】:

我在这里做错了什么?

...
using (var ctx = ObjectContextManager<MyDataContext>.GetManager("MyDataContext"))
{
    var idsToUpdate = "2,3";

    var parameters = new[]
    {
         new SqlParameter("DesiredEndDate", SqlDbType.DateTime).Value = newUpperLimit,
         new SqlParameter("TasksToUpdate", SqlDbType.NVarChar).Value = idsToUpdate
    };

    ctx.ObjectContext.ExecuteStoreCommand("UPDATE dbo.Tasks SET DesiredEndDate = @DesiredEndDate WHERE Id IN (SELECT Id FROM dbo.fn_Split(@TasksToUpdate, N','))", parameters);

    ctx.ObjectContext.SaveChanges();
}
...

我得到了错误

必须声明标量变量“@DesiredEndDate”。

必须声明标量变量“@TasksToUpdate”。

但我看不出我的代码有什么问题:/

【问题讨论】:

  • 不确定您使用 @DesiredEndDate 时遇到的错误,但使用 IN (@TasksToUpdate) 的方法无论如何都行不通。
  • 我已经通过使用硬编码值手动执行查询对其进行了测试。你能解释一下为什么你认为这是错误的吗?
  • 这行不通。这将与Id IN ('1,2')Id IN (1,2) 不一样
  • 你是对的。感谢您指出。更新。但是仍然遇到相同的错误:(

标签: c# sql-server entity-framework


【解决方案1】:

我仍然不明白为什么@ParamName 语法不起作用。但是有一个替代方案,它确实有效:

 ctx.ObjectContext
    .ExecuteStoreCommand(
          "UPDATE dbo.Tasks SET DesiredEndDate = {0} WHERE Id IN (SELECT Id FROM dbo.fn_Split({1}, N','))",
          newUpperLimit, 
          idsToUpdate);

这有一个额外的好处,我不需要创建SqlParameters。

【讨论】:

  • 如果newUpperLimitidsToUpdate 不能保证采用安全格式,您可能会遇到SQL 注入问题。
  • 这里不可能进行 SQL 注入。在内部,ExecuteStoreCommand 使用 DbCommand。 CreateParameter 传递参数。请参阅 Josh Gallagher 在stackoverflow.com/questions/5474264/… 中的评论。
  • 啊有趣。我没仔细看TBH。我看到了{0},只是以为你在做字符串连接。
【解决方案2】:

问题是你的代码:

var parameters = new[]
{
     new SqlParameter("DesiredEndDate", SqlDbType.DateTime).Value = newUpperLimit,
     new SqlParameter("TasksToUpdate", SqlDbType.NVarChar).Value = idsToUpdate
};

不是创建SqlParameters 的数组 - 它实际上是创建一个包含 2 个Value 属性的数组。您可以通过将代码更改为此(不会编译)来确认这一点:

var parameters = new SqlParameter[]
{
     new SqlParameter("DesiredEndDate", SqlDbType.DateTime).Value = newUpperLimit,
     new SqlParameter("TasksToUpdate", SqlDbType.NVarChar).Value = idsToUpdate
};

还有这个(会编译)

var parameters = new SqlParameter[]
{
     new SqlParameter("DesiredEndDate", SqlDbType.DateTime),
     new SqlParameter("TasksToUpdate", SqlDbType.NVarChar)
};

parameters[0].Value = newUpperLimit;
parameters[1].Value = idsToUpdate;

您也可以这样做:

var param1 = new SqlParameter("DesiredEndDate", SqlDbType.DateTime);
param1.Value = newUpperLimit;
var param2 = new SqlParameter("TasksToUpdate", SqlDbType.NVarChar);
param2.Value = idsToUpdate;

ctx.ObjectContext.ExecuteStoreCommand("...", param1, param2);

【讨论】:

  • 酷。我确信我已经按照我之前在问题中显示的方式完成了它并且它有效。感谢您的解释。原来 SqlParameters 变量是不必要的。
猜你喜欢
  • 2019-07-14
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 2021-08-16
  • 2021-07-16
  • 2012-07-30
  • 1970-01-01
相关资源
最近更新 更多