2

Stack Overflow と Google を検索するときに、状況に対する明確な答えを見つけるのに苦労しています。うまくいけば、誰かが私を正しい方向に向けることができます。

私の状況 ASP.NET MVC 3 および Entity Framework 4 CTP (コードファースト) を使用して、単一の編集フォーム (単一のビュー内) を使用して、3 レベルの深さの階層エンティティを更新できるようにしたいと考えています。多くのサービス オプションを持つことができるサービスは、多くのインベントリ アイテムを持つことができます。

MVC の既定のモデル バインダーを (TryUpdateModel 経由で) 使用できることを期待していました。

  1. 既存の「サービス」レコードを更新する
  2. 投稿された値に応じて、「サービス オプション」レコード (サービスに添付) を追加/更新/削除します。
  3. 投稿された値に応じて、「在庫」レコード (各サービス オプションに添付) を追加/更新/削除します。

私のモデル

    [Bind(Include="Name, ServiceOptions")]
public class Service {
    [Key]
    public int ServiceID { get; set; }      
    public string Name { get; set; }        
    public DateTime DateCreated { get; set; }
    public virtual ICollection<ServiceOption> ServiceOptions { get; set; }
}

[Bind(Include="ServiceOptionID, Description, Tags")]
public class ServiceOption {
    [Key]
    public int ServiceOptionID { get; set; }
    public int ServiceID { get; set; }  /* parent id reference */
    public string Description { get; set; }
    public virtual ICollection<Inventory> InventoryItems { get; set; }
}


[Bind(Include = "InventoryID, Description")]
public class Inventory {
    [Key]
    public int InventoryID { get; set; }
    public int ServiceOptionID { get; set; }  /* parent id reference */
    public string Description { get; set; }
}

理想的なコントローラーの方法:

    [HttpPost]
public ActionResult EditService(int id) {
    Service service = db.Services.Single(s => s.ServiceID == id);
    TryUpdateModel(service); // automatically updates child and grandchild records

    if (ModelState.IsValid) {               
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(service);
}

このユートピアの夢を実現する方法はありますか、それとも間違った木を吠えていますか? 別のテクノロジー (通常の EF4、Automapper など) を使用することにオープンです。

前もって感謝します!

4

1 に答える 1

0

デフォルトのモデル バインダーだけで?おそらくそうではありません。

カスタムで?おそらく。

ただし、問題はモデル バインダー自体ではありません。あなたの問題は、EFとORM、および(私が思うに)一般に、コレクションからアイテムを削除操作として削除することを考慮していないことです。実際、ORM に伝えているのは、関係が存在しないということであり、子行を削除する必要があるということではありません。マッピングによっては、通常、「参照整合性制約違反が発生しました」のようなエラーが発生します。これは、コードが最初にあるためではありません。これは、EF のしくみです。

EF は設計上このように動作し、他の m2m リレーションシップを参照する m2m リレーションシップがある場合など、より複雑なリレーションシップにとって非常に重要です。リレーションシップを削除するための呼び出しと、行を完全に削除するための呼び出しを EF で明確にできるようにする必要があります。

また、IMHO、この手法も悪いです。なぜなら、http 値のマッピングを担当するコードに、オブジェクトの永続化方法も指示するからです。これは悪い動きです。私は、削除操作は非常に神聖な行為であり、ModelBinder だけに任せるべきではないと考えています。論理的な削除やログ記録を行わずにオブジェクトを削除することは、"重大なビジネス" と見なす必要があります。

于 2011-01-24T01:05:52.333 に答える