我有一个存储过程,它有三个参数,我一直试图使用以下代码返回结果:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
起初我尝试使用SqlParameter
作为参数但这不起作用,抛出了一个包含以下信息的SqlException
:
存储过程或函数'mySpName'需要参数'@param1',但未提供。
因此我的问题是如何在需要参数的存储过程中使用此方法?
谢谢。
我有一个存储过程,它有三个参数,我一直试图使用以下代码返回结果:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
起初我尝试使用SqlParameter
作为参数但这不起作用,抛出了一个包含以下信息的SqlException
:
存储过程或函数'mySpName'需要参数'@param1',但未提供。
因此我的问题是如何在需要参数的存储过程中使用此方法?
谢谢。
您应按以下方式提供SqlParameter实例:
context.Database.SqlQuery<myEntityType>(
"mySpName @param1, @param2, @param3",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2),
new SqlParameter("param3", param3)
);
DbNull.Value
而不是 null 值可以解决问题吗? - Alireza此外,您可以将"sql"参数作为格式说明符:
context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
ProcName @optionalParam1 = @opVal1,@optionalParam2 = @opVal2
。有效的示例:ProcName @optionalParam1 = {0},@optionalParam2 = {1}
。 - Garrison Neely这个解决方案仅适用于SQL Server 2005
你们是救星,但正如@Dan Mork所说,你需要在混合中添加EXEC。让我困惑的是:
:
context.Database.SqlQuery<EntityType>(
"EXEC ProcName @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
exec
关键字。另外,去掉参数前面的 @ 符号会更好,因为它总是让我感到困惑。 - Nathan Koopreturn context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 });
//或
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
}
//或者
using(var context = new MyDataContext())
{
object[] parameters = { param1, param2, param3 };
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
parameters).ToList();
}
//或者
using(var context = new MyDataContext())
{
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
param1, param2, param3).ToList();
}
大多数答案很脆弱,因为它们依赖于存储过程参数的顺序。更好的方法是命名存储过程参数并为它们提供参数化值。
要在调用存储过程时使用命名参数,而不必担心参数的顺序
使用ExecuteStoreQuery和ExecuteStoreCommand的SQL Server命名参数
描述了最佳方法。比Dan Mork在这里的回答更好。
例如:
var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var sqlParams = new[]{
new SqlParameter("name_param", "Josh"),
new SqlParameter("age_param", 45)
};
context.Database.SqlQuery<myEntityType>(cmdText, sqlParams)
sqlParams
变量。 - Don Cheadledb.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()
或者
db.Database.SqlQuery<myEntityType>(
"exec GetNewSeqOfFoodServing @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
或者
var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param";
var @params = new[]{
new SqlParameter("name_param", "Josh"),
new SqlParameter("age_param", 45)
};
db.Database.SqlQuery<myEntityType>(cmdText, @params)
或者
db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);
我喜欢它,因为我只需要输入Guids和Datetimes,SqlQuery就可以为我执行所有的格式化操作。
using(var db = new ProFormDbContext())
{
var Action = 1;
var xNTID = "A239333";
var userPlan = db.Database.SqlQuery<UserPlan>(
"AD.usp_UserPlanInfo @Action, @NTID", //, @HPID",
new SqlParameter("Action", Action),
new SqlParameter("NTID", xNTID)).ToList();
}
不要重复使用sqlparameter,有些人会因此而烧毁他们的变量。
var Action = new SqlParameter("@Action", 1); // Don't do this, as it is set below already.
public static object GetDBNullOrValue<T>(this T val)
{
bool isDbNull = true;
Type t = typeof(T);
if (Nullable.GetUnderlyingType(t) != null)
isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
else if (t.IsValueType)
isDbNull = false;
else
isDbNull = val == null;
return isDbNull ? DBNull.Value : (object) val;
}
(此方法的功劳归于https://stackoverflow.com/users/284240/tim-schmelter)
然后像这样使用:
new SqlParameter("@parameterName", parameter.GetValueOrDbNull())
或者另一个更简单但不是通用的解决方案是:
new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
当我使用调用存储过程的方式,传递两个输入参数并使用SELECT语句返回3个值时,遇到了相同的错误信息。在EF Code First方法中,我通过以下方式解决了这个问题。
SqlParameter @TableName = new SqlParameter()
{
ParameterName = "@TableName",
DbType = DbType.String,
Value = "Trans"
};
SqlParameter @FieldName = new SqlParameter()
{
ParameterName = "@FieldName",
DbType = DbType.String,
Value = "HLTransNbr"
};
object[] parameters = new object[] { @TableName, @FieldName };
List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();
public class Sample
{
public string TableName { get; set; }
public string FieldName { get; set; }
public int NextNum { get; set; }
}
更新:看起来在 SQL SERVER 2005 中缺少 EXEC 关键字会创建问题。所以为了让它适用于所有的 SQL SERVER 版本,我更新了我的答案并在下面一行添加了EXEC
List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();