2

NHibernate をサービス層から分離しようとして、壁にぶつかりました。私のアーキテクチャは次のようになります。

ウェブ -> サービス -> リポジトリ -> nhibernate -> db

サービス層と、場合によっては Web 層から nhibernate クエリを生成できるようにしたいと考えています。現在、すべてのリポジトリに を取り込む find メソッドがありますIList<object[]> criterianew object() {"Username", usernameVariable};これにより、アーキテクチャのどこからでも、基準のリストを渡すことができます。NHibernate はこれを取り込み、新しい Criteria オブジェクトを作成し、渡された基準を追加します。これは、サービス レイヤーからの基本的な検索では問題なく機能しますが、リポジトリが NHibernate Criteria に変換するクエリ オブジェクトを渡す機能が必要です。

本当に、この質問で説明されているようなものを実装したいと思います: Is there value in abstracting nhibernate criteria。このようなものを実装する方法についての良いリソースが見つかりません。その質問で説明されている方法は良いアプローチですか?もしそうなら、そのようなソリューションを実装する方法について誰かがいくつかの指針を提供できますか?

4

2 に答える 2

9

ORM を抽象化すると、次のようになります。

  • そのAPIを再定義する多くの作業をもたらします
  • データベース アクセスの最適化/バッチ処理を不可能にする
  • どのクエリが実行されるかを理解するのがずっと難しくなる
  • 大量の SELECT N+1 につながる

そして、ほとんど価値がありません: ORM フレームワークを交換する漠然としたオプションは、おそらく他にも多くの問題を抱えています。

  • 欠けている機能
  • 実装の微妙な違い
  • 学習曲線

更新:経験

私はかつて、既存の DAL 抽象化の新しいプロバイダーの実装に携わっていました。アプリケーションがデフォルトの実装を想定していたため、最終的にパフォーマンスが低下し、多くのバグが発生しました。エラー処理は混乱し、古いデータを使用することもありました。理由:

  • キャッシングはコンテキストを認識しません
  • キャッシュ実装には異なるセマンティクスがありました
  • 抽象化するにはあまりにも異なるバッチ API
  • エラーは実装に固有のものです (例: FileNotFound -> FilesearchDialogは tcp/ip ベースのデータベースには役に立ちません)
  • エラー回復は異なります (各実装には、回復可能な独自のエラー セットがあります)
  • ロック機構が違いました
  • SQL データベースに一貫した変更イベントがない
  • ネストされたトランザクション
  • Model クラスでのデフォルトの実装の出血
  • 抽象化されたすべてのクエリを再実装するのは大変な作業であり、多くのコピー ペースト バグが発生しました。
  • 順序を明示的に指定せずにクエリを実行すると、異なる実装では異なる順序の結果が返されます

アプリケーションの多くのリファクタリングが必要でした:

  • 1 つの実装のみが提供する機能を取り除く
  • 実装ごとのキャッシュ管理
  • 一時的なデータによるラッパーの識別の問題
  • 2 つのデータストアに対するクエリの実装が非常に難しい

追加のポイント:

  • 抽象 DAL を介したデータの移行は非常に遅い
  • 上記の問題のために、さらに別の実装を実装することは決してありません。コストがかかりすぎるためです(前述のシナリオでは、プロジェクト全体をゆっくりと再実装し始めました)
  • 純粋な API には使用のコンテキストがないため、DAL API の正しいセマンティクスを実装することは非常に困難でした。

(ビジネス タスクの) 移植は、パフォーマンスのためにいくつかの移植を行ったので、IMO の痛みはずっと軽減されたはずです。

Update2: エクスペリエンス 2: NHibernate から EntityFramework に移植しようとしている間の RoadBlocks (NH で実装しましたが、妥当な時間内に EF 4 でできませんでした)

  • ネストされたトランザクション
  • 列挙型のサポート
  • compositeId を使用した参照 (referenceId を取り除く方法)
  • コンポーネント内の参照
  • 一度にページ+カウントに便利なバッチ処理(先物)を読む
  • CultureInfo のマッピング (IUserType のサポート)
于 2012-10-16T10:57:55.170 に答える
0

回答ありがとうございます。あなたの言っていることは理解できますが、これらの回答は私の問題を解決しません。私が書いているシステムの状態のため、アーキテクチャを変更することができません。代わりに、何らかの複雑なクエリ クラスをサービスに公開しようとするのではなく、すべての sql/hql/criteria API クエリをリポジトリ レイヤー内に保持するだけです。このアプローチは問題なく機能するはずです。ただし、次のアーキテクチャのアプローチでは、他の回答で指摘された点を検討します。

于 2012-10-16T14:09:16.233 に答える