c# - entity framework sql parameters




ストアドプロシージャでDbContext.Database.SqlQuery<TElement>(sql、params)を使用する方法 EFコードファーストCTP5 (6)

2つの入力パラメータを取り、SELECT文を使用して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; }
}

更新 :EXECキーワードが見つからないSQL SERVER 2005の問題が発生しているようです。 だからそれはすべてのSQL Serverのバージョンで動作するように私の答えを更新し、下の行でEXECを追加

 List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();

私は3つのパラメータを持つストアドプロシージャを持っており、私は結果を返すために次を使用しようとしています:

context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);

最初は、 SqlParameterオブジェクトをparamsとして使用しようとしSqlParameterが、これはうまくいかず、 SqlExceptionれました。次のメッセージが表示されます。

プロシージャまたは関数 'mySpName'には、パラメータ '@ param1'が指定されていますが、これは指定されていません。

だから私の質問は、パラメータを期待するストアドプロシージャでこのメソッドを使用する方法ですか?

ありがとう。


@ Tom Halladayの答えは、あなたがshopuldで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://.com/users/284240/tim-schmelter送られhttps://.com/users/284240/tim-schmelter )

次に、次のように使用します。

new SqlParameter("@parameterName", parameter.GetValueOrDbNull())

よりシンプルですが一般的なものではないでしょう:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)

ほとんどの回答は、SPのパラメータの順序に依存しているため、脆弱です。 Stored Procのパラメータに名前をつけ、パラメータ化された値をそれらのパラメータに与える方がよいでしょう。

パラメータの順序を気にせずにSPを呼び出すときに名前付きパラメータを使用するには

ExecuteStoreQueryおよびExecuteStoreCommandでのSQL Server名前付きパラメータの使用

最良のアプローチについて説明します。 ここのDan Morkの答えよりも良い。

  • 文字列の連結に依存せず、SPで定義されたパラメータの順序に依存しません。

例えば:

var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var params = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

context.Database.SqlQuery<myEntityType>(cmdText, params)

また、 "sql"パラメータを書式指定子として使用することもできます。

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)

私はこの方法を使用します:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);

GuidsとDatetimesをドロップするだけで、SqlQueryはすべてのフォーマットを実行するので、私はそれが好きです。


db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

@ p0、@ p1、@ p2 ......
または

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();






entity-framework-ctp5