web-dev-qa-db-ja.com

Entity Frameworkを使用してストアドプロシージャからデータを取得する

GridViewコントロールを設定するために、(Entity Framework 6.1.1を使用して)データベースコンテキストオブジェクトから呼び出される動的SQLストアドプロシージャを使用して、テーブルのコンテンツを取得しようとしています。データを取得できません。

これがストアドプロシージャです。これは、ストアドプロシージャでのSQLインジェクションに関する学生デモ用です。したがって、I KNOWこれはインジェクション可能であり、問​​題ありません。

_ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END
_

次にストアドプロシージャを実行するために使用するC#コードは次のとおりです。

_var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.SearchProducts(TEST_SEARCH_TERM);

MyGridView.DataSource = result;
MyGridView.DataBind();
_

Visual Studioのデータベースエクスプローラーで実行すると、ストアドプロシージャは正常に動作します。しかし、実行中のASP.NETアプリで実行すると、resultIEnumerableDataSetではなく_-1_を返すため、DataBind()メソッドで例外が発生します。ストアドプロシージャのSELECTの結果のオブジェクトを含む。

データを取得してGridViewを設定するにはどうすればよいですか?

32
mak

この問題を解決するには、次の手順を使用します。

  1. ストアドプロシージャを関数としてインポートする必要があります。エンティティモデルのワークスペース領域を右クリックし、Add -> Function Importを選択します。
  2. [関数インポートの追加]ダイアログで、たとえばSearch_Productsなど、モデルで参照するストアドプロシージャの名前を入力し、ドロップダウンリストからプロシージャを選択し、プロシージャの戻り値をEntitiesに選択します。ドロップダウンリストからProductsを選択します。
  3. 次に、コードビハインドで:

    var db = new MyEntities();
    var TEST_SEARCH_TERM = "product";
    var result = db.Search_Products(TEST_SEARCH_TERM);//Search_Products is the name that you specified in Function Import dialog
    
    MyGridView.DataSource = result;
    MyGridView.DataBind();
    

結果として-1を取得する理由は、Entity Frameworkがそのままストアドプロシージャの戻り値をサポートできないためです。ストアドプロシージャの戻り値のサポートは、Entity Frameworkのバージョンに依存すると思います。また、Entity Frameworkは、SQLの代わりではなくORMであるため、豊富なストアドプロシージャをサポートしていません。

30
Salah Akbari

動的SQLを使用するストアドプロシージャでこれに遭遇しました。 「SET FMTONLY OFF;」という行を追加すると、複雑な型を使用して成功しました。 ( https://msdn.Microsoft.com/en-us/library/ms173839.aspx を参照)EFモデルに追加する前に、ストアドプロシージャの先頭に。複合型を使用してモデルをセットアップしたら、必ずこの行を削除してください。

例:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SET FMTONLY OFF;
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END
3
gotmilk13531

問題を解決したようです。Microsoftの公式ドキュメントが以下のリンクから入手できます。

ストアドプロシージャをエンティティデータモデルにインポートする方法: https://msdn.Microsoft.com/en-us/library/vstudio/bb896231(v = vs.100).aspx

EFデザイナーの複雑なタイプ: https://msdn.Microsoft.com/en-gb/data/jj680147.aspx

最新バージョンの.netを使用していることを確認し、データベースに変更を加えたときにモデルを最新の状態に保ちます。

0
user1641172

EDMXに戻りタイプがあることを確認します。[関数のインポート]-> [SearchProducts]に移動し、ダブルクリックします。

Complex戻り値型を使用するには、Entity Frameworkでは、*を使用する代わりに、ストアドプロシージャで列名を明示的に定義する必要があります。

ストアドプロシージャを変更して列名を定義したら、プロジェクトのモデルを更新できます。 (注:SPを完全にドロップし、それをedmxに追加し直すのが最善の方法です。)

[〜#〜] edit [〜#〜]

次のようにSPを変更できます。

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SELECT * FROM dbo.Products WHERE Name LIKE '%' + @SearchTerm + '%'
END
0
Vahlkron