0

現在、リポジトリ パターンと Entity Framework 5 を ORM として使用して、内部システムを開発しています。

データベースには、呼び出す一連のストアド プロシージャがあります。これらのプロシージャの中には、類似したパラメータ名を持つものがあります。したがって、ストアド プロシージャを実行する呼び出しを行うと、次のようになります。

DbContext.Database.SqlQuery<ReturnType>(query, parameters)

結果の列挙型は、同様のパラメーター名を持つ別のプロシージャへの 2 回目の呼び出しで失敗し、次のように述べています。

ArgumentException がユーザー コードによって処理されませんでした: SqlParameter は、別の SqlParameterCollection に既に含まれています。

すべてSqlParametersをコレクションに入れ、ループしてコレクション内のすべてのアイテムを無効にしようとしましたが、これも失敗します....見事に。

このスタック トレースで Object 配列にアクセスして操作する方法はありますか?

System.Data.SqlClient.SqlParameterCollection.Validate (Int32 インデックス、オブジェクト値)
で System.Data.SqlClient.SqlParameterCollection.AddRange (配列値)
で System.Data.Objects.ObjectContext.CreateStoreCommand (文字列 commandText、オブジェクト [] パラメーター)
System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](文字列 commandText、文字列 entitySetName、MergeOption mergeOption、Object[] パラメーター)
で System.Data.Objects.ObjectContext.ExecuteStoreQuery[TElement](文字列 commandText、Object[] パラメーター)
System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery[TElement] (文字列 sql、オブジェクト [] パラメーター)で
System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable[TElement] (文字列 sql、オブジェクト [] パラメーター)
で System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery (型 elementType、文字列 sql、オブジェクト [] パラメーター)
で.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
System.Data.Entity.Internal.InternalSqlQuery 1 ソース) 1.GetEnumerator()
at System.Linq.Enumerable.First[TSource](IEnumerable

4

5 に答える 5

0

この問題を解決できませんでした。組み込みの SqlQuery メソッドのコマンド オブジェクトは、SQL パラメータをクリアしていないようですが、回避策があります。現在の接続に基づいて独自のコマンドを作成できますが、戻り値の型を簡単にマップする機能は失われます。

public void CallStoredProc(string query, List<SqlParameter> parameters)
{
    //this.Database.Connection (this = DBContext)
    System.Data.Common.DbCommand cmd =  this.Database.Connection.CreateCommand();
    cmd.CommandText = query;

    // add params
    foreach (var item in parameters)
    {
        cmd.Parameters.Add(item);
    }

    // execute query (not differed)
    var reader = cmd.ExecuteReader();


    // attempt to read rows
    if (reader.HasRows)
    {
        while (reader.Read())
        {
            // row level data
        }
    }

    // cleanup
    cmd.Parameters.Clear();
    cmd.Dispose();
}
于 2013-10-25T12:38:01.257 に答える
0

この問題を回避するための解決策を見つけました。ストアド プロシージャの呼び出しは、実行後に破棄される新しい DbContext をインスタンス化するために行われます。

IEnumerable<ReturnType> Results = null;

using (DbContext NewContext = new PrometheusEntities())
{
    Results = NewContext.Database.SqlQuery<ReturnType>(query, parameters).ToList();    
}    
return Results;

この方法を採用して以来、私は何の問題も経験していません。

于 2013-11-14T21:56:31.947 に答える