0

ASP.NET MVC3Editアクションに、編集するオブジェクトではなく新しいオブジェクトが与えられるのはなぜですか?
ID 値が指定されたオブジェクトのプロパティを調べるとunsaved-value、NHibernate マッピング ファイルで指定した値になります。

これを回避するには、データベースからオブジェクトをクエリして更新し、メソッドに渡されたオブジェクトから必要なプロパティを設定します。しかし、これは 1 つまたは 2 つのプロパティを持つ非常に単純なオブジェクトでは問題なく機能しますが、多くのプロパティがあり、システムと戦っているように見えるとすぐに問題になります (これは、私が行っていないことを示しています)。物事が行われることになっている方法)。

私のマッピング:

<id name="Id" column="Id" type="Guid" 
    unsaved-value="00000000-0000-0000-0000-000000000000">

私の編集方法:

[NHibernateActionFilter]
[HttpPost]
public ActionResult Edit(Status status, Guid id)
{
    try
    {
        if (ModelState.IsValid)
        {
            var originalStatus = Session.QueryOver<Status>()
                                        .Where(s => s.Id == id)
                                        .SingleOrDefault<Status>();
            if (originalStatus == null)
                throw new Exception(string.Format("No Status with Id: {0}.", id));

            originalStatus.StatusName = status.StatusName;
            Session.Update(originalStatus );

            return RedirectToAction("Index");
        }
    }
    catch (DataMisalignedException ex)
    {
        // TODO: Log4Net this
        ModelState.AddModelError("", "Unable to save changes. Please try again.");
    }
    return View(status);
}

*これは、Ayende による摩擦のない無臭のコードへのリファクタリングNHibernateActionFilterに関する一連の投稿から取られ、それで装飾されたコントローラーの各アクションに ISession を与えます。しかし、それが問題の原因ではないと思います。

私の問題は、アイテムを編集しようとすると発生し、 aStaleObjectExceptionがスローされます。

行が別のトランザクションによって更新または削除されました (または、保存されていない値のマッピングが正しくありませんでした): [TheWorkshop.Web.Models.Status#00000000-0000-0000-0000-000000000000]

新しい Guid は、言及されたステータスが新しいものであり、詳細ビューを設定するために以前に返されたオブジェクトではないことを示しています。したがって、新しいオブジェクトが更新されて EditActionResultに渡されたように見えますが、これは役に立ちません。

上で示したように、コードを書くことはできますが、それは解決策というよりハックです。Edit メソッドを次のように残すことができるようにしたいと思います。

[NHibernateActionFilter]
[HttpPost]
public ActionResult Edit(Status status)
{
    try
    {
        if (ModelState.IsValid)
        {
            Session.Update(status);

            return RedirectToAction("Index");
        }
    }
    catch (DataMisalignedException ex)
    {
        // TODO: Log4Net this
        ModelState.AddModelError("", "Unable to save changes. Please try again.");
    }
    return View(status);
}

編集更新エンティティの処理方法の回答
を見てきました。NHibernate + ASP.NET MVCですが、それは私が既に行ったことのほとんどを実行し、更新方法が私の試みのように面倒である必要があるとは信じられません。

また、このエラーが nhibernate で何を意味するかを調べました。それは私の問題と同じように見えますが、私にとってはうまくいく答えが得られませんでした。つまり、問題はまだ解決していません。

4

2 に答える 2

3

アクション メソッドに提供されるStatusインスタンスは、MVC のモデル バインダーによって生成されます。モデル バインダーと NHibernate はお互いについて何も知らないため、これは新しいオブジェクトです。正しい ID を持つようにするには、フォームの一部として ID を提供する必要があります (非表示)。ただし、フォームに含まれるフィールドよりも多くのフィールドを投稿したり、非表示フィールドの値を変更したりして、ユーザーが許可されていない変更を加えないように注意してください。

モデルが違うのはよくあることです。MVC はフロント エンドでビュー モデルを使用しますが、これは目的が異なり、ドメイン モデルと必ずしも同じように見えるとは限りません。アクション メソッドは、ビュー モデルの値に基づいて動作し、ドメイン モデルで正しいアクションを実行します。

于 2013-03-04T07:41:17.250 に答える
0

正しいとマークする必要があるOskersの回答に何も追加することはできません。ほんの数点です。

元のメソッドでは、Ayende の属性がトランザクションを作成するため、update ステートメントは必要ありません。NHibernate は属性が変更されたことを確認し、それを更新します。

2 番目の方法が適していると思われる場合は、Nhibernate オブジェクトにロードされるカスタム モデル バインダーを作成することでこれを実現できます。

参照: ASP.NET MVC モデル バインディングの外部キー関係

于 2013-03-04T20:49:15.100 に答える