私のASP.NET MVCアプリケーションでは、ドメインモデルをビューモデルから切り離しました。
viewmodelオブジェクトでエンティティを変換するので、必要なデータだけでビューを「フィード」することができます(この目的のためにvalueinjecterを使用しました)。
保存プロセス中に、コントローラがviewmodelオブジェクトを取得し、それをドメインモデルエンティティに変換し、SaveOrUpdateで永続化しようとします。 既存のレコードを更新しようとすると、Nhibernateはそれを新しいオブジェクトと見なし、エンティティが適切なIDを持っていてもINSERTを強制します。
すべてのフィールドを再度マップすることを避けたいので、前にエンティティをロード(ロード/ロード)していません。
私が間違っていることはありますか?それを達成する最良の方法は何ですか?NhibernateでSaveOrUpdateの前にエンティティをロード/取得する必要がありますか?
***** - UPDATE - ***
私のコントローラは、ユーザ(ViewModelに)を受信し、それを検証し、エンティティとしてサービス層を介して、それを保存しようと:
public ActionResult Edit(Guid id, Models.User User)
{
...
var user = new Domain.User();
user.InjectFrom(User);
user.SetId(id);
user = this._SecurityService.SaveUser(user);
}
これはサービスです:
public Domain.User SaveUser(Domain.User User)
{
bool Result = false;
if (this._ValidationEngine.IsValid(User))
{
using (_UnitOfWork)
{
if (User.Code != Guid.Empty)
{
var user = this._UserRepository.Load(User.Code);
user.InjectFrom(User);
User = this._UserRepository.Update(user);
}
else {
User = this._UserRepository.Save(User);
}
Result = _UnitOfWork.Commit();
}
}
return (User);
}
私は私のビューモデル/エンティティを何度も変えなければならないという事実を心配しています。今すぐ新しいユーザーを保存しようとすると、次のメッセージが表示されます。行が別のトランザクションによって更新または削除されました(または保存されていない値のマッピングが正しくありませんでした)
おそらくこれはDarinが私に言っていることと関係しています。
私がやろうとしていることを行うためのより良い方法はありますか?私はエラーことに気付きました
UPDATE「行が更新または削除されました...」は、私は私のマッピングのために定義されたバージョンを持っていることに起因します。私が理解できるのは、Idとバージョンを、更新したいエンティティと一致させる必要があるということです。
DDD + ASP.NET MVC + NHibernateで他の人がこれらのことをどのように行うのかを理解したいですか?
SOLUTION
私のすべてのエンティティは、バージョンが定義されている(私は、申し訳ありませんと言うのを忘れて):
<version name="Version" type="System.Int32" unsaved-value="0">
<column name="Version" not-null="true" />
</version>
Ayendeはhereを説明したように、NHibernateのは、このようなクエリで私のエンティティを更新しよう:
UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y
ここで、yは自分のエンティティのバージョンである必要があります。エンティティにバージョンを設定していないので、StaleObjectException例外が生成されます。
私はviewmodelにバージョンフィールドを追加しました。私はIDと一緒に私のビューの隠されたフィールドにそれを保存します。
私のコントローラは、IDとバージョンのビューモデルを受け取るようになりました。 私は(私は私のエンティティをリロードしないでください)私のドメインエンティティにこれらのフィールドを注入し、リポジトリは、それを保存してみましょう:
User = this._UserRepository.Update(user);
私はStaleObjectException例外を取得した場合、それは他の誰かがDBの行を更新したことを意味私はユーザーにいくつかのフィードバックを提供します。
エンティティを読み込んで再マップしてみてください(私はこのようにしたくないと知っています)。これを試してみてください。 – Omu
私の問題はバージョンであると思います。私のマッピングに定義されている <バージョン名> "バージョン"タイプ= "System.Int32未保存値=" 0 "> <カラム名="バージョン "not-null =" true "/> – LeftyX