我有一个存储过程,有三个参数,我一直试图使用以下命令返回结果:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
起初,我尝试使用SqlParameter对象作为参数,但这并不奏效,并抛出了一个SqlException与以下消息:
过程或函数“mySpName”需要未提供的参数“@param1”。
我的问题是如何将此方法用于期望参数的存储过程?
谢谢。
我有一个存储过程,有三个参数,我一直试图使用以下命令返回结果:
context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);
起初,我尝试使用SqlParameter对象作为参数,但这并不奏效,并抛出了一个SqlException与以下消息:
过程或函数“mySpName”需要未提供的参数“@param1”。
我的问题是如何将此方法用于期望参数的存储过程?
谢谢。
当前回答
@Tom Halladay的回答是正确的,提到你也可以检查空值,如果参数为空,就发送DbNullable,因为你会得到一个异常
参数化查询'…'需要参数'@parameterName',该参数没有提供。
像这样的东西帮助了我
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)
其他回答
大多数答案都是脆弱的,因为它们依赖于SP参数的顺序。最好是为Stored Proc的参数命名,并为它们提供参数化值。
为了在调用SP时使用Named参数,而不用担心参数的顺序
使用SQL Server命名参数的ExecuteStoreQuery和ExecuteStoreCommand
描述最佳方法。比丹·莫克的回答更好。
不依赖于串接字符串,也不依赖于SP中定义的参数顺序。
例如:
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)
@Tom Halladay的回答是正确的,提到你也可以检查空值,如果参数为空,就发送DbNullable,因为你会得到一个异常
参数化查询'…'需要参数'@parameterName',该参数没有提供。
像这样的东西帮助了我
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();
return 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();
}
我用的是EF 6。X是这样的:
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.