1

EntitySet を持つ Linq to Sql Entity があります。私のビューでは、エンティティとそのプロパティに加えて、子エンティティの編集可能なリストを表示します。ユーザーは、これらの子エンティティを動的に追加および削除できます。DefaultModelBinder はこれまでのところ正常に動作し、子エンティティを正しくバインドします。

今私の問題は、削除された子エンティティを削除するためにLinq To Sqlを取得できないことです。新しいエンティティは喜んで追加されますが、削除されたエンティティは削除されません。外部キー関係でカスケード削除を有効にしました。Linq To Sql デザイナーは外部キー関係に "DeleteOnNull=true" 属性を追加しました。次のように子エンティティを手動で削除すると:

myObject.Childs.Remove(child);
context.SubmitChanges();

これにより、DB から子レコードが削除されます。しかし、モデルにバインドされたオブジェクトに対しては機能しません。私は次のことを試しました:

// this does nothing
public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
    var obj2 = _repository.GetObj(id); // obj2 has 6 child entities
    if(TryUpdateModel(obj2)) //it sucessfully updates obj2 and its childs
    {
         _repository.SubmitChanges(); // nothing happens, records stay in DB
    }
    else
         .....

    return RedirectToAction("List");
}

これは InvalidOperationException をスローします。私はドイツ語の OS を使用しているため、英語のエラー メッセージが正確にはわかりませんが、エンティティにバージョン (タイムスタンプ行?) が必要であるか、または更新チェック ポリシーがないという行に沿って何かを示しています。 . 主キー列を除くすべての列に UpdateCheck="Never" を設定しました。

public ActionResult Update(MyObject obj)
{
    _repository.MyObjectTable.Attach(obj, true);
    _repository.SubmitChanges(); // never gets here, exception at attach
}

Linq To Sql で同様の「問題」について多くのことを読んだことがありますが、これらの「問題」のほとんどは実際には設計によるものです。それで、これがうまくいくと思ったようにうまくいかないという私の仮定は正しいですか?子エンティティを手動で反復処理し、それらを手動で削除、更新、および挿入する必要がありますか? このような単純なオブジェクトの場合はうまくいくかもしれませんが、入れ子になった EntitySet などを使用してより複雑なオブジェクトを作成する予定です。これは、何が機能し、何が機能しないかを確認するための単なるテストです。これまでのところ、Linq To Sql にはがっかりしています (単に理解できないだけかもしれません)。このシナリオでは、Entity Framework または NHibernate がより適切な選択でしょうか? または、同じ問題に遭遇しますか?

4

1 に答える 1

0

.NET4に付属するEntityFrameworkで確実に機能します(RCバージョンでも同様のことを行っています)

これは例外を説明していません

ObjectContext(ほとんどの場合)リポジトリにラップされているものを破棄する必要があります。コンテキストはアイテムをキャッシュし、単一の作業単位にのみ使用する必要があります。

次のようなパターンを使用してみてください。

public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities
{
    using(var repository = CreateRepository())
    {
        var obj2 = _repository.GetObj(id);
        if(TryUpdateModel(obj2))
        {
             repository.SubmitChanges();
        }
        else
            .....
    }

    return RedirectToAction("List");
}

アイテムをフェッチするときは、新しいリポジトリも作成します。それらは作成と廃棄が安価であり、可能な限り迅速に廃棄する必要があります。

于 2010-03-30T21:27:56.980 に答える