3

簡単に:

パラメータを受け入れる C# メソッドがあります。

そのメソッド内に、Sql パラメーターを追加する必要があります (メソッドパラメーターに従って)。

実際には次のようになります: http://i.stack.imgur.com/QP1y2.jpg (拡大) ここに画像の説明を入力

注意してください

すべてのメソッド引数を持つクラスを作成できます。ただし、各 SP のクラス コンテナーを作成する必要があります (そして、たくさんあります)。

では続けましょう。

私は自分自身に考えていました:「なぜ各パラメーターを手動で挿入する必要があるのですか? メソッドのパラメーターに : nametypeが既にある場合はvalue?私はこれをやりたくないので、おそらくリフレクションが私のためにこれを行うでしょう」(今のところ残しましょうの変換int <->DbType.Int32)

しかし、問題が発生しました。リフレクションを使用して値を読み取ることはできません。

ただし、ハックでリフレクションを介して値を読み取ることができました。

1)私はこの例を行いました:(実際のシナリオへのシミュレーション)

public static void MyMethod(int AddressId, string countryId, DateTime dt) //these are the arguments which need to be attached later
{

 MethodBase mi = MethodInfo.GetCurrentMethod();
 var hack = new {AddressId, countryId, dt}; //this is the HACK


var lstArguments = mi.GetParameters()  //get the parameter  name and types
                    .Select(p => new {
                                 name = p.Name  , type=p.GetType().Name
                                 }).ToList();


List < dynamic > lstParamValues= new List < dynamic > ();

foreach(PropertyInfo pi in hack.GetType().GetProperties())  //get the value(!!!) of each param 
{

       lstParamValues.Add(pi.GetValue(hack, null));
}


  dynamic dyn= myDBInstance; // get dynamic reference to the DB class instance ( 

for(int i = 0; i < lstArguments .Count; i++) //dynamically Invoke the method with param name+value.
{
    dyn.AddInParameter(lstArguments [i].name, ((lstParamValues[i] is int) ? DbType.Int32 : DbType.String), lstParamValues[i]);
}

}

そしてDBクラスがあります(値を取得するかどうかをシミュレートするため)AddInParameter

class myDB
{
    public void AddInParameter(string name, DbType dbt, object val)
    {
        Console.WriteLine("name=" + name + "    " + "DbType=" + dbt + "    " + "object val=" + val);
    }
}

そしてそれは働いています:

私はメソッドを実行しました:

MyMethod(1, "2", DateTime.Now);

出力は次のとおりです。

name=AddressId    DbType=Int32    object val=1
name=countryId    DbType=String    object val=2
name=dt    DbType=String    object val=05/02/2013 19:09:32

大丈夫だ。

C# の質問

このハックを乗り越えるにはどうすればよいですか:

 var hack = new {AddressId, countryId, dt};  //  the method arguments names

私のサンプルでは、​​ハードコーディングして書きました。

リフレクションメソッドGetValueは、この行のためにのみ機能しています。

実行時にメソッド引数名をプロパティとして追加するためにできることはありますか?

 foreach(PropertyInfo pi in SOMETHING.GetType().GetProperties()) 
   {
   }

この質問は、ORM の質問ではなく、ac# の質問と考えてください。

また、実行中のサンプル コードで遊びたい場合 (コンソール プロジェクトに貼り付けるだけ): http://jsbin.com/azicut/1/edit

4

3 に答える 3

0

AddWithValue少なくとも、型名を書く必要がなくなります。

 command.Parameters.AddWithValue("@demographics", demoXml);

しかし、実際にはそれほど多くのパラメーターを関数に渡さないでください。単純なDTOクラスを使用すると、コードをはるかに読みやすくすることができます。私が間違っていなければ、キーと値のペアとして関数のローカル変数を提供するpyhton localspythonのlocalsのようなものが必要)のようなものを探していますが、私が知る限り、c#ではこれを行うことはできません。

または、単純にすべての変数を渡すのではなく、渡すだけDictionary<string,object>でSqlParameterにキー値を追加できます。

于 2013-02-05T17:55:25.987 に答える
0

これはいくらかの安心を提供しますか?

これを1回行います(DAL ctorで):

SqlParameter sqlCmdFTSindexWordOnceParam = sqlCmdFTSindexWordOnce.Parameters.Add("@sID", SqlDbType.Int);
sqlCmdFTSindexWordOnceParam.Direction = ParameterDirection.Input;
SqlParameter sqlCmdFTSindexWordOnceParam2 = sqlCmdFTSindexWordOnce.Parameters.Add("@sIDpar", SqlDbType.Int);
sqlCmdFTSindexWordOnceParam2.Direction = ParameterDirection.Input;

次に、呼び出しで:

sqlCmdFTSindexWordOnceParam.Value = wdc.sID;
sqlCmdFTSindexWordOnceParam2.Value = wdc.sIDpar;                                    
sqlCmdFTSindexWordOnce.BeginExecuteNonQuery(callbackFTSindexWordOnce, sqlCmdFTSindexWordOnce);

呼び出しごとにパラメーターを追加するよりもパフォーマンスが向上します。

于 2013-02-05T17:49:08.913 に答える
-3

私はc#と.netの動作に精通していませんが、これがjavaの場合、次のように言います。

現在のパラメータを配列リストまたはマップに保存します

addInParametersメソッド呼び出しに入るパラメーターごとに1つずつ、合計3つの配列リストを作成するか、すべての値が含まれているマップを作成できます(typeパラメーターは現在のように複製する必要があります)。

配列リストを挿入/更新メソッドの唯一のパラメーターとして使用するforループを使用して、AddInParameter呼び出しが1回だけ書き込まれ、パラメーターが(array1 [0]、array2 [0]、array3 [0])のようになります。実際の値より。

PHPでは連想配列を使用できますが、.netには連想配列がありますか?

于 2013-02-05T17:38:31.190 に答える