0

私はEF5コードファーストを使用しています:

public class Scenario
{
    public int Id { get; set; }
    public  IList<Client> Clients { get; set; }
}
public class Client
{
    public int Id { get; set; }
    public string Name {get;set;}
    public int VisibilityNumber{ get; set; }
}

シナリオオブジェクトをビューに直接送信しています(MVC4、viewmodelクラスを使用せずに-おそらく間違いですか?しかし、配管コードははるかに少ないです)。私の見解では、HiddenForforScenario.Idとforループを使用して各クライアントVisibilityNumberのEditForを表示しています。

これはコントローラーです:

[HttpPost]
public ActionResult Edit(int id, FormCollection formValues)
{     
if (ModelState.IsValid)
    {
        Scenario scen=GetScenarioFromDB(id);
        TryUpdateModel(scen,formValues);
        if (ModelState.IsValid)
           SaveToDb(scen);
    }
}

TryUpdateModelの後、各Clientsオブジェクト(DBから正しくロードされたもの)に対して:

  • VisibilityNumberが正しく設定されている
  • Idは0に設定されていますが、これはもちろん悪いことです
  • 名前がnullに設定されている

MVCソースコード(DefaultModelBinder / UpdateCollection)を確認すると、コレクションにバインドするときに、常に新しいアイテムが作成されることがわかります。それを修正できない場合は、viewModelとAutoMapperを使用すると思います。MVCチームは、EFオブジェクトを直接送信するのではなく、viewModelを使用するように強制したいと考えています。

4

2 に答える 2

0

scenarioアップデートでデータベースから取得するべきではありません。代わりに、バインドされたモデルを取得し、それを(編集されている場合)アタッチするか、(新しい場合)コンテキストに追加してから、変更を保存する必要があります。これは「切断されたエンティティ」と呼ばれる一般的なシナリオです(実際には、クライアントに送信されたときに切断された後、再び切断されたモデルがあるため、実際にあります)。

于 2012-08-31T18:55:24.147 に答える
0
  1. DefaultModelBinder / UpdateCollectionを「修正」して、ユースケースで機能できるようにしました。バインディングがナビゲーションプロパティでドリルダウンしている場合、現在のオブジェクトをモデルとして使用します(変更のみを行い、挿入や挿入は行わないため、簡単です。削除):DefaultModelソースコードを取得し、修正を加えて、カスタムモデルバインダーとして使用できます。それは楽しいですが、少し汚くて上にあります。
  2. しかし、最善の方法は、編集可能なプロパティのみを使用して特定のViewModelを使用し、AutoMapを使用してそれをEF階層にマップすることだと思います。ただし、子オブジェクトコレクションを作成する場合と同じ問題があります。
  3. 最後に、ビューモデルとEF階層の間で手動マッピングを実行しました。子アイテムが変更、挿入、または削除されたかどうかを検出できる自動処理を実行できるとほぼ確信しています(すべてのアイテムに[key]プロパティですが、それを実装するための時間予算がありません。
于 2012-08-31T23:33:09.853 に答える