2012-05-13 9 views
1

私が取り組んでいる新しいプロジェクトのための私の要件の1つは、すべてのSQLクエリがストアドプロシージャを使用しなければならないということです。私はEntity Framework &を使ってデータアクセスを管理し、リポジトリには "Find(predicate)"と "FindAll()"メソッドがあります。現時点では、どちらも同じストアドプロシージャ(「select * from Foo」)を使用しています。LINQ式はどのようにストアドプロシージャで動作しますか?

私はSQLプロファイラにアクセスできないので、Find(predicate)メソッドでLINQ式がどのように変換されるのかよくわかりません。私のようなものを持っている場合:

List<Foo> myFoo = repository.Find(f => f.Country == "Australia" && f.Status = "New"); 

私はメモリ内フィルタ処理結果のデータと、SPROCを介して、すべてのレコードを取得するでしょうこれを仮定して修正するのですか?この場合、どのようにして同時に必要なレコードを取得するだけで、linq式を使用できるようにするためにsprocを構造化できますか?(& &、||、!= etc)を許可する必要がありますか? sprocsを捨てなくてもこれは可能ですか?

+2

クエリ構成LINQとクエリ-sprocsを同時に効率的に使用することは事実上不可能です。基本的には、sprocsの周りにラッパーコードを書くための精巧な方法としてEFを使用しています。 –

答えて

3

すべてのストアドプロシージャを使用する必要がある場合は、EFを使用することはあまり意味がありません。実際、EFの最大の利点の1つは、データの取得/挿入/更新/削除のための厳格な数のパラメータと適切なクエリのsintaxを使用して、自動的にクエリを生成することです。

あなたが失うEFの二つの利点があります。

  • ナビゲーションを、すなわち、容易すなわち、熱心明示的または遅延読み込みと、
  • 形のデータを関連データを取得するプロパティを持つエンティティを取得するには、他のエンティティまたはエンティティの集合
  • 単純なCRUD操作(不活性/更新/削除/選択)の自動生成。この操作にstoed procsを指定することができます
  • データベースが単にモデルを変更するだけであれば、適切なクエリを得ることができます(EFを使用する方法によってはほぼ自動的に行うことができます)。アドホックフィルタに関連する保存されprocsのにクエリの *自動生成を変更する必要があります(異なる列以上の異なるSETOF条件を持つフィルタ)

あなたはEFは、クエリを生成させない場合は、簡単ではありませんナビゲーション、形状データ、適切なクエリの自動生成、フィルタなどがあります。あなたがモデルで本当に大変な作業をしている場合にのみ、Somefotが可能になります。あなたがEFを使用している場合しかし、あなたはあなたのモデルを更新した場合、変更内容の一部が失われる可能性がすると、データベースに

を形成し、保存されprocsのを使用することが正当化される機会は、次のとおりです。

  • あなたがデータを変更する必要がありますEFで直接変更できないもの(古いバージョンのEFで更新可能なクエリはサポートされていませんでした)
  • EFで生成されたクエリではなく、使用するストアドプロシージャを最適化しました。
  • 多くのことをするストアドプロシージャ(単純な挿入/更新/削除や選択ではないものプロシージャ)
  • ストアドプロシージャが自動的に生成されたクエリに対していくつかの利点を提供する他の場合。

残りのすべての質問については、EFがあなたに適しています。

すべてのストアドプロシージャを使用する必要がある場合は、EFを使用する利点はデータのエンティティへの自動マッピングですが、EFの他の多くの利点が失われます。あなたがこれを行う必要があるでしょう

  • あなたは別のデータのように多くのエンティティを定義する必要があります保存されprocsの
  • フォームが返されますが、各ストアドプロシージャをマッピングする必要があります関数(関数にマップされている)、モデル(edmx)を変更して、挿入/更新/削除に使用するプロシージャを知らせます。

それらの間に関係があるエンティティ間の関係でモデル化する。

repository.Find(...)に関する質問に対して、あなたが正しいとすれば、すべてのデータが照会され、クライアント側でフィルタリングされます。最悪の場合、モデルが正しく定義されていないと、失敗する可能性があります。

EFでクエリを作成させると、サンプルに似た単一のケースでDBに適切なフィルタが送信されます。 特定の方法でフィルタリングする特殊なストアドプロシージャがある場合は、LINQを忘れて、マップされた関数を直接呼び出す必要があります。

したがって、SPを使用するのが正当な理由がない限り、EFにクエリを作成させる方がよいでしょう。

+0

少し遅れて私の質問を更新しましたが、私は少しばかげて同じ結論に達しました。私たちは当分の間、sprocの要件を落としてしまいました。パフォーマンスが問題になった場合(そのようには見えません)、sprocの要件を再確認します。 –

1

あなたがしていることは、すべてのレコードを取得してメモリにフィルタリングするという意味で正しいものです。私は式とsprocsを構成することは不可能だと言っていない限り行くことはありませんが、それは非常に非実用的で、おそらく最初にあなたのsprocの要件の目的を敗北させるでしょう。式ツリーを解釈してパラメータ化されたsqlを生成し、それをsprocに渡すか(おそらくsproc要件の目的に反する)、または式ツリーを解釈して、引数を「ジェネリックsproc」に適切に渡す必要があります。 "一般的"とは、フィルタリングしたいものに対してはnull値のパラメータを持つことを意味します(かなり非実用的で、多くの制限があります - 結合などはありません)。

sprocの要件を尊重しているならば、IQueryableを公開しているあらゆるデータアクセスAPIをあきらめます(メモリ内の式を実行する意思がない限り、式とsprocsを作成する能力は失われます) 。

Eotaは、式とsprocsとの間の合成ができない場合でも、モデルを扱う際の利便性とむしろ定型的な騒ぎを避けることができます。

関連する問題