我正在将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,但是仍然出现此错误。困惑...
答案 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
推定为Object
和string
的最低公分母。
不幸的是,对ExecuteStoreCommand
的调用不会给您任何警告,表示您未通过int
,因为根据文档,它接受非常弱的类型SqlParameter[]
:>
参数值可以是DbParameter对象的数组或参数值的数组
要解决此问题,您可以使用直接采用该值的params object[]
构造函数之一,例如
SqlParameter
或者创建参数,分配它们,然后添加到数组中。
出于兴趣,var paramList = new[]
{
new SqlParameter("@Value", "SomeValue"),
new SqlParameter("@FkId", 123)
};
是ObjectContext
上的一种方法,而不是DbContext。
有一个等效的方法DbContext.Database.ExecuteSqlCommand
应该做同样的事情。