1

私が取り組んでいる新しいプロジェクトの要件の1つは、すべてのSQLクエリでストアドプロシージャを使用する必要があることです。Entity Frameworkとリポジトリパターンを使用してデータアクセスを管理し、リポジトリには「Find(predicate)」メソッドと「FindAll()」メソッドを使用します。現時点では、両方とも同じストアドプロシージャを使用しています(「select * fromFoo」)。

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

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

これがsprocを介してすべてのレコードを取得し、結果のデータがメモリ内でフィルタリングされると想定するのは正しいですか?この場合、必要なレコードのみを取得すると同時にlinq式の使用を許可するようにsprocを構成するにはどうすればよいですか(&&、||、!=などを許可する必要があります)。これは、sprocを捨てなくても可能なことですか?

4

2 に答える 2

3

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

EFには、次の2つの利点があります。

  • ナビゲーション、つまり、熱心な、明示的な、または遅延読み込みを使用して、関連データを簡単に取得する
  • 整形されたデータ、つまり、他のエンティティまたはエンティティのコレクションが持つプロパティを持つエンティティを取得します
  • 単純なCRUD操作(不活性化/更新/削除/選択)の自動生成。この操作のstoedprocを指定できます
  • データベースが変更された場合に適切なクエリを取得するモデルを変更するだけです(EFの使用方法によっては、ほぼ自動で実行できます)データが変更された場合は、関連するストアドプロシージャを変更する必要があります*自動生成アドホックフィルター(異なる列に対して異なる条件のセットを持つフィルター)のクエリ

EFにクエリを生成させないと、簡単なナビゲーション、整形されたデータ、適切なクエリの自動生成、フィルターなどができなくなります。モデルで非常にハードな作業を行った場合にのみ、いくつかのクエリが可能になります。ただし、データベースからモデルを更新すると、変更の一部が失われる可能性があります

EFを使用している場合、使用されるストアドプロシージャが正当化されるのは次のとおりです。

  • EFで直接変更できないデータを変更する必要があります(つまり、古いバージョンのEFで更新可能なクエリがサポートされていなかった場合)
  • EFによって生成されたクエリの代わりに、使用するストアドプロシージャを最適化しました。つまり、複雑なフィルタを最適化しました。
  • 多くのものを作成するストアドプロシージャ(単純な挿入/更新/削除または選択プロシージャではないもの)
  • ストアドプロシージャが自動生成されたクエリよりも優れているその他の場合。

残りのすべてのクエリについては、EFに作業を任せる方がはるかに優れています。

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

これを行う必要があります:

  • ストアドプロシージャから返されるさまざまなデータと同じ数のエンティティを定義する必要があります
  • ストアドプロシージャを適切なエンティティ(関数にマップされている)、関数にマップするか、モデル(edmx)を変更して、挿入/更新/削除および取得に使用するプロシージャを通知する必要があります。

エンティティ間に関係があるエンティティ間の関係を持つモデルを定義するのは難しいでしょう。

最良の場合についての質問についてrepository.Find(...)は、その通りです。すべてのデータが照会され、クライアント側でフィルタリングされます。最悪の場合、モデルが適切に定義されていないと、失敗する可能性があります。

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

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

于 2012-05-14T01:22:22.563 に答える
1

正解です。箱から出してすぐに、すべてのレコードを取得し、メモリ内でフィルタリングします。式やsprocを作成することは不可能だとまでは言いませんが、それは非常に非現実的であり、そもそもsproc要件の目的を損なう可能性があります。式ツリーを解釈してパラメーター化されたSQLを生成し、それをsprocに渡す(おそらくsproc要件の目的を無効にする)か、式ツリーを解釈して引数を「汎用sproc」に適切に渡す必要があります。「汎用」とは、フィルタリングしたいものすべてに対してnull許容パラメーターがあることを意味します(かなり実用的ではなく、多くの制限があります-結合などはありません)。

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

JotaBeが指摘したように、式とsprocの間の構成可能性がなくても、EFはモデルを処理し、かなり定型的な煩わしさを回避するのに便利です。

于 2012-05-14T01:28:18.573 に答える