「スタブテクニック」を使用してPOCOを更新しています(分離されたコンテキスト、ASP.NET MVCで使用されます)。
これは私が現在私のコントローラーに持っているコードです(これは機能します):
[HttpPost]
public ActionResult Edit(Review review)
{
Review originalReview = _userContentService.FindById(review.PostId) as Review;
var ctx = _unitOfWork as MySqlServerObjectContext;
ctx.ApplyCurrentValues("MyEntities.Posts", review);
_unitOfWork.Commit();
// ..snip - MVC stuff..
}
ご覧のとおり、いたるところにコードの臭いがあります。:)
いくつかのポイント:
- 基本的にすべてに依存性注入(インターフェースベース)を使用します
- Unit of Workパターンを使用して、ObjectContextを抽象化し、複数のリポジトリ間で永続性を提供します
- 現在、私のIUnitOfWorkインターフェイスには1つのメソッドしかありません。
void Commit();
- コントローラーはDIによって注入し
IUserContentService
ますIUnitOfWork
IUserContentService
Find
を使用するリポジトリでの呼び出しObjectContext
。
これらは、上記のコードでは気に入らない2つのことです。
- IUnitOfWorkをとしてキャストしたくありません
MySqlServerObjectContext
。 - コントローラーに気を配らせたくない
ApplyCurrentValues
基本的に、コードは次のようになります。
[HttpPost]
public ActionResult Edit(Review review)
{
_userContentService.Update(review);
_unitOfWork.Commit();
// ..snip - MVC stuff..
}
どのように私はそれを行うことができますか?(または同様のもの)。
タイプ(ジェネリックスの組み合わせ、複数化)に基づいてエンティティセット名を計算するための賢い方法はすでにあるので、それほど心配する必要はありません。
しかし、私はどこに置くのApplyCurrentValues
が最適なのか疑問に思っていますか?IUnitOfWork
これは永続性(EF)の問題であるため、インターフェイスに配置することは適切ではないようです。同じ理由で、それはサービスに属していません。これをクラスに入れるとMySqlServerObjectContext
(意味があります)、このクラスに直接アクセスできるものはないため、どこから呼び出すのでしょうか。何かが要求すると、DIを介して注入されますIUnitOfWork
。
何かご意見は?
編集
以下にスタブ手法を使用した解決策がありますが、問題は、更新しているエンティティを事前に取得した場合、そのキーを持つエンティティがすでに存在することを示す例外をスローすることです。
どうすればこれを解決できるかわかりませんが、どちらが理にかなっていますか?
「エンティティがすでにアタッチされているかどうかを確認し、アタッチされていない場合はアタッチする」必要がありますか?
EF4の専門家は助けてくれますか?
編集
気にしないでください-解決策を見つけました。以下の回答を参照してください。