私は3つのパラメータを持つストアドプロシージャを持っていて、結果を返すために以下を使用しようとしていました:
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)
);
また、フォーマット指定子として "sql"パラメータを使用することができます。
context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
この解決策はSQL Server 2005用の(のみ)です
皆さんは命の恩人ですが、@ Dan Morkが言ったように、ミックスにEXECを追加する必要があります。私をつまずかせたのは、
:
context.Database.SqlQuery<EntityType>(
"EXEC ProcName @param1, @param2",
new SqlParameter("param1", param1),
new SqlParameter("param2", param2)
);
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();
}
ほとんどの答えは、SPのパラメーターの順番に依存しているため、もろいです。 Stored Procのパラメータに名前を付けてパラメータ化された値をそれらに与えるほうがよい
SPの呼び出し時にパラメータの順序を気にせずに名前付きパラメータを使用するため
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)
db.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が私のためにすべてのフォーマットを実行するので、私はそれが好きです。
@Tom Halladayの答えは、あなたが買い物客にnull値もチェックし、paramsがnullの場合は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ステートメントを使用して2つの入力パラメーターを受け取り、3つの値を返すストアード・プロシージャーを呼び出して作業していたときに同じエラー・メッセージが表示され、EFコード優先アプローチで以下のような問題を解決しました。
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; }
}
UPDATE:SQL Server 2005でEXECキーワードがないと問題が発生しているようです。だから私は私の答えを更新し、次の行にEXECを追加したすべてのSQL Serverバージョンで動作するようにします。
List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();