ORMとの組み合わせでマスター詳細ビューを最適に実装する方法がわかりません。 アプリケーションは、MVVMでWPFを使用し、現在選択されているオブジェクトの詳細だけでなく、使用可能なすべてのオブジェクトのグリッドを表示します。 ItemViewModel
は、ビュー内の表示手段であるべきドメインオブジェクトのViewModelにあるORM、作業単位およびリポジトリパターンと組み合わせたマスター - 詳細ビュー
ObservableCollection<ItemViewModel> Items
を:ビューのViewModelには、それが持っている、非常に単純です。このプロパティはグリッドにバインドされています。
- グリッドの
SelectedItem
にバインドされItemViewModel CurrentItem
プロパティ。 「選択した項目を削除」と「選択したアイテムへの変更を保存」、「新しい項目の追加」の ICommand
。
私のアプリケーションはそのORMツールとしてNHibernateはを使用していますが、私はそう、私は「作業単位」と「リポジトリ」のパターンを使用して、それを抽象化コードベース全体でNHibernateはをリークする必要はありません。
これらのパターンのNHibernate固有の実装は、「Unit of Work」が新しいNHibernateセッションを開き、トランザクションが開始時と終了時にトランザクションをコミットし、セッションを処分するようなものです。したがって、作業単位、セッション、およびトランザクションの存続期間は同じです。作業ユニットは、作業ユニットと同じセッションを使用しており、同じ寿命を持つプロパティーRepository
を持っています。
ここで問題が発生しています。 MasterDetailViewModel
のコンストラクタにItems
コレクションを移入したいとします。現在、私は新しい作業ユニットを作成してコレクションに移入する必要があります。トランザクションが長期間実行されないようにするために、UoWは直後に処理され、基礎となるセッションも破棄されます。
現在、ユーザーが現在のアイテムの変更を保存したい場合、別のUoWを開き、データベースからエンティティを取得し、ItemViewModel
の現在の値で更新し、データベースに保存して処分する必要がありますうわー。
しかし、このアプローチは、いくつかの重要なドローバックを持っています
- 私のコードは
using(var uow = uowFactory.StartNew())
が散らばっています。 - 楽観的なロックが行われていません。他の誰かがデータベース内の同じアイテムを変更してしまった場合、その変更は黙って上書きされます。
- 項目を1つではなく更新するには、2つのデータベースヒットが必要です。
これは私のUoWの実装に欠陥があるという結論につながります。
私はUOWとリポジトリとの間の関係が逆転するように実装を変更することを考えました。これは、IoCがUnitOfWorkFactoryではなくViewModelにリポジトリを挿入することを意味します。リポジトリは、NHibernateのISession
と機能的に同等です。リポジトリは、データベーストランザクションと同じ新しいUoWを開始することができます。
これは私のマスター/詳細シナリオにはうまくいくが、通常は作業単位の同義語として使用される「ビジネストランザクション」の概念をサポートしていない。複数のデータベーストランザクションとユーザー要求にまたがる論理トランザクション。
質問です:最高の両方のシナリオで使用できるように仕事とリポジトリの二つのパターンのユニットを実装する方法は?
見ます表示されている項目を参照)、各業務オペレーション "新規追加"、 "変更"などの周りのtransaction.Begin()、transaction.Commit()を使用します。 – Firo
@Firo:この場合、長期間のセッションが良いことであることを私に保証してくれてありがとう。 –