FromSqlRawを介してEF Core 3.0でストアドプロシージャを呼び出す方法


10

最近、EF Core 2.2からEF Core 3.0に移行しました。

残念ながら、エンティティを返すストアドプロシージャを呼び出す方法が見つかりませんでした。

EF Core 2.0では、次のことが可能でした。

var spParams = new object[] { "bla", "xx" };
var createdPath = ModelContext.Paths.FromSql("AddNodeWithPathProc  @p0, @p1", spParams).Single();

EF Core 3.0では、メソッドFromSQLはに置き換えられていFromSqlRawます。ただし、ストアドプロシージャを正常に呼び出してから、値を処理できませんでした。これは、ストアード・プロシージャーがデータベースにデータを挿入するときに役立ちます。

EF Core 3.0では、次のコードを使用します。

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc @p0, @p1", spParams).Single();

ただし、生成されたSQLは無効であり、次のように見えるため、例外がスローされます。

exec sp_executesql N'SELECT TOP(2) [p].[PathId], [p].[Level], [p].[NodeId], [p].[NodePath], [p].[NodePathString]
FROM (
     @sql @p0, @p1
) AS [p]',N'@p0 nvarchar(4000),@p1 nvarchar(4000), @sql nvarchar(100)',@p0=N'1a',@p1=N'', @sql=N'AddNodeWithPathProc'

かなりの数のバリエーションを試しましたが、成功しませんでした。

でストアドプロシージャを実行することはできないと思い始めていますModelContext.[IQueryable].FromSqlRaw。私の意見FromSqlRawでは、通常の選択ステートメントの場合、通常LINQで十分なため、この種類は主な理由の1つを打ち負かします。

誰かがストアドプロシージャFromSqlRawをEF Core 3.0 と組み合わせて使用​​する方法を知っていますか?どんな助けでも大歓迎です。

前もって感謝します

PS:でストアドプロシージャを実行できることは知っていますthis.Database.ExecuteSqlRaw(SQL, parameters)。ただし、この方法では、ストアドプロシージャがクエリするエンティティを取得することはできません。


2
.Single()の代わりに.ToList()を試してください。.Single()は「TOP(2)」ラッパーを生成しています。
デビッドブラウン-マイクロソフト、

当面の一時的な回避策は次のとおりです。this.ModelContext.ExecuteRawSql( "EXEC AddNodeWithPathProc @ p0、@ p1"、spParams); var createdPath = ModelContext.Paths.FromSqlRaw( "SELECT TOP 1 * FROM dbo.Path ORDER BY PathID DESC")。Single(); ただし、これは本番環境では許容できるソリューションではありません。
Dan

はい.. ToList()は機能します..ありがとうございました:-)
Dan

回答:


6

解決策(David Browneに感謝します。回答として投稿しておく必要があります):

シングルをToListに置き換えると動作します:-)

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc  {0}, {1}", nodeTitle, parentPathString).ToList();

1
var result=context.yourmodelclass.FromSqlInterpolated($"StoredProcedureName {param1},{param2}").tolist();

必要に応じて、複数のパラメーターを追加できます。注意:

  • context =>データベースの名前。
  • yourmodelclass =>ストアドプロシージャの結果から出力結果をフェッチするために作成するモデルフォルダ内のクラス。

0

私はテストできる場所ではありませんが、以下が機能すると思います:

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc {0}, {1}", parm1 parm2).Single();

1
いいえ、これは機能しません。ちょうどそれをテストしました。無効なSQL :-(。生成されたSQLと関係があると思います。プロファイラーでSQLをチェックすると、常にスキーマに従います:sp_executesql 'SELECT * FROM {mySqlPassedInMethod}。私はそうしません。このコードでストアドプロシージャを渡す方法を知っています。したがって、.netメソッドは、渡されたsql文字列がストアドプロシージャ用であることを検出し、それに応じて生成されたsqlを適応させるか、T-SQLにない方法があります。知っている(私は専門家ではありません)
Dan

0

SqlParameterを分離してみます。

SqlParameter param1 = new SqlParameter("@p0","value");
SqlParameter param2 = new SqlParameter("@p1","value");

var createdPath = ModelContext.Paths.FromSqlRaw("AddNodeWithPathProc @p0 @p1", param1, 
param2).Single();

削除した投稿の解決策を以下に投稿しました。
jdweng

試してみましたが失敗しました:-(。エラーは次のとおりです: "System.InvalidCastException: 'SqlParameterCollectionはnull以外のSqlParameterタイプのオブジェクトのみを受け入れ、SqlParameterオブジェクトは受け入れません。'"。SQLサーバーに送信されたSQLがありません(によるとsqlプロファイラ)
Dan

@jdwengどうもありがとう:)ソフトウェアにログインし、最後に更新された最新のXMLファイルを最後の日付でダウンロードしたときにこの解決策がありましたが、履歴のすべての履歴データが欠落していないことが必要です。だから私は日付を設定し、レートでExcelファイルをダウンロードする別のオプションがありますが、それを実装する方法がわかりません。サーバーでサービスを実行しますか?ユーザーが1週間ソフトウェアを使用しないので、1週間の為替レートを逃しました。
ISTech

@ISTech:次のページをご覧ください:boi.org.il/en/Markets/Pages/explainxml.aspx日付にURLを追加できます。 boi.org.il/currency.xml?rdate=20120101
jdweng

@ISTech:日付の範囲を指定するために以下のコードを更新しました。
jdweng

0

それは非常に奇妙です...数日前に私は同じ問題を抱えており、この投稿に従います。私はこの電話をしました:

 public IEnumerable<TableChange> GetTableLastChanges(string tableName, string keyColumn, out int synchronizationVersion)
    {
        var parameters = new[] {
            new SqlParameter("@table_name", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = tableName },
            new SqlParameter("@key_column", SqlDbType.VarChar) { Direction = ParameterDirection.Input, Value = keyColumn },
            new SqlParameter("@synchronization_version", SqlDbType.BigInt) { Direction = ParameterDirection.InputOutput, Value = 0 }
        };

        var changes = this.TableChanges.FromSqlRaw("[dbo].[GetTableLastChanges] @table_name, @key_column, @synchronization_version OUTPUT", parameters).ToList();

        synchronizationVersion = Convert.ToInt32(parameters[2].Value);

        return changes;
    }

現在、すべてが問題なく、この呼び出しは期待どおりに機能します。したがって、Core 3のEFのデータセットとパラメーターの戻り値に問題がないことを認めなければなりません。


0

ここを見てください:

https://github.com/DarioN1/SPToCore

これはストアドプロシージャの足場であり、spの操作に役立ちます。

3番目のパーツライブラリではなく、プロジェクトに含める純粋なc#コードを生成し、現在のdbContextを拡張して、ストアドプロシージャメソッド、パラメーターマッピング、およびクラス分けされた結果を提供します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.