データ アクセスに NHibernate を使用する ASP.NET MVC 2 RC アプリケーションのモデル バインドに問題があります。Ruby on Rails の方法でアプリケーションを構築しようとしており、ドメイン エンティティがデータベースからビューまでずっと使用される非常に単純なアーキテクチャを持っています。
アプリケーションには、次の 2 つのクラスで示すことができるドメイン エンティティがいくつかあります。
public class Product {
...
public Category Category { get; set; }
}
public class Category {
public int Id { get; set; }
public string Name { get; set; }
}
編集フォームをレンダリングするビューには、ドロップダウン リストを表示する次のステートメントがあります。
<%= Html.DropDownListFor(model => model.Category.Id,
new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"),
"-- Select Category --" ) %>
カテゴリ コレクションを保持するために「型指定されていない」ビュー データを使用することは無視してください。
フォーム ポストを受け取るアクション メソッドは次のようになります。TransactionFilter 属性は NHibernate トランザクション処理を追加し、例外が発生せず、検証が成功した場合にトランザクションをコミットすることに注意してください。
[HttpPost]
[TransactionFilter]
public ActionResult Edit(int id, FormCollection collection) {
var product = _repository.Load(id);
// Update the product except the Id
UpdateModel(product, null, null, new[] {"Id"}, collection);
if (ModelState.IsValid) {
return RedirectToAction("Details", new {id});
}
return View(product);
}
私の問題は、product.Category.Id がフォームで選択された値で設定されていることです。たとえば、Category.Id = "2" です。デフォルトのモデル バインダーを使用すると、次のタイプの NHibernate 例外が発生します。
identifier of an instance of Name.Space.Entities.Category was altered from 4 to 2
製品にはすでにカテゴリが割り当てられており、その既存のカテゴリの主キーのみが変更されているため、これは非常に理にかなっています。代わりに、別のカテゴリ インスタンスを割り当てる必要があります。
この問題を処理するためにカスタム ModelBinder を作成できると思いますが、これを機能させる簡単な方法はありますか? これを処理するためにドメイン エンティティを変更できますか (また変更する必要がありますか)。