试图使用带有EF的SqlParameters运行插入,得到标量变量错误,如何解决?

时间:2019-04-07 13:01:38

标签: c# entity-framework entity-framework-6

我正在将EF 6与MVC5 / C#一起使用

我正在尝试通过EF上的SqlParameter使用ExecuteStoreCommand对象运行插入语句。我这样做是因为AddObject遇到一些性能问题。

我的代码是:

string insertCmd = "INSERT INTO TABLE (Value,FkId) VALUES (@Value,@FkId)";

var paramList = new[]{
    new SqlParameter("@Value", SqlDbType.VarChar).Value = value,
    new SqlParameter("@FkId", SqlDbType.Int).Value = fkId
};

db.ExecuteStoreCommand(insertCmd, paramList);

我遇到了错误:

  

必须声明标量变量“ @Value”。无法准备声明。

我注意到,无论类型如何,它总是抱怨Insert语句的第一列。因此,如果我将其交换,我将得到:

  

必须声明标量变量“ @FkId”。无法准备声明。

有想法吗?

编辑:

仅注意到记录已插入并保存到DB,但是仍然出现此错误。困惑...

1 个答案:

答案 0 :(得分:2)

如果您仔细查看编译器为该变量推断的类型:

var paramList = new[]
{
    new SqlParameter("@Value", SqlDbType.VarChar).Value = "SomeValue",
    new SqlParameter("@FkId", SqlDbType.Int).Value = 123
};

您会看到paramList是具有两个标量值Object[2]Value(string)的{​​{1}},而123(int)完全丢失了,因为分配的结果就是分配的值!编译器将SqlParameters推定为Objectstring的最低公分母。

不幸的是,对ExecuteStoreCommand的调用不会给您任何警告,表示您未通过int,因为根据文档,它接受非常弱的类型SqlParameter[]

  

参数值可以是DbParameter对象的数组或参数值的数组

要解决此问题,您可以使用直接采用该值的params object[]构造函数之一,例如

SqlParameter

或者创建参数,分配它们,然后添加到数组中。

出于兴趣,var paramList = new[] { new SqlParameter("@Value", "SomeValue"), new SqlParameter("@FkId", 123) }; ObjectContext上的一种方法,而不是DbContext。

有一个等效的方法DbContext.Database.ExecuteSqlCommand应该做同样的事情。