1

次の EntityObject ベースの EF モデルがあります (コードをよりクリーンに保つためのフィールドとしてここに記述されたプロパティ)。

Booking 
{
   int BookingID;
   EntityCollection<BookingCustomer> BookingCustomers;
   string Notes;
}

BookingCustomer 
{
   Customer Customer;
   Booking Booking;
   int CustomerID;
   int BookingID;
   string Notes;
}

Customer 
{
   int CustomerID;
   string Name;
}

私は切り離された方法でオブジェクトグラフをロードしています:

Booking existingBooking;
using(MyContext ctx = new MyContext())
{
    ctx.Bookings.MergeOption = MergeOption.NoTracking;
    ctx.BookingCustomers.MergeOption = MergeOption.NoTracking;
    ctx.Customers.MergeOption = MergeOption.NoTracking;
    existingBooking = ctx.Bookings
       .Include("BookingCustomers")
       .Include("BookingCustomers.Customer")
       .First();
}

予約と顧客データの変更:

existingBooking.Notes = "Modified";
existingBooking.BookingCustomers.First().Name += " Edited";

保存:

using(MyContext ctx = new MyContext())
{
        ctx.Bookings.Attach(existingBooking);
        ctx.ObjectStateManager.GetObjectStateEntry(existingBooking ).SetModified();
        ctx.Refresh(RefreshMode.ClientWins, existingBooking);    
        ctx.SaveChanges();
} 

(既存のレコードが更新されるのではなく)新しい顧客レコードが作成されます。

私もこれを試しました:

using(MyContext ctx = new MyContext())
{
    ctx.Customers.Attach(existingBooking.BookingCustomers.First());
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking.BookingCustomers.First()).SetModified();
    ctx.Refresh(RefreshMode.ClientWins, existingBooking.BookingCustomers.First());

    ctx.Bookings.Attach(existingBooking);
    ctx.ObjectStateManager.GetObjectStateEntry(existingBooking ).SetModified();
    ctx.Refresh(RefreshMode.ClientWins, existingBooking);    
    ctx.SaveChanges();
} 

しかし、オンラインで例外を取得していますctx.Customers.Attach(existingBooking.BookingCustomers.First());:

System.InvalidOperationException: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

どうすればそれを機能させることができますか?

4

2 に答える 2

1

ラディスラフは正しいです。ただし、この問題を解決し、デタッチされたモデルを保持できるようにするために検討すべきオプションがもう 1 つあります。セルフ トラッキング POCO です。オブジェクト グラフがその状態を追跡できるようにする T4 テンプレート (VS2010 にバンドルされているか、ダウンロードとして利用可能) があります (これには、グラフへのオブジェクトの追加/削除、およびオブジェクトのどのプロパティが変更されたかが含まれます)。変更を加えたグラフを再接続できます。EF4 は変更を把握し、それらをオブジェクト状態マネージャーに適用します。

于 2011-08-04T09:38:57.027 に答える
1

リフレッシュすることではありません。デタッチされた状態でグラフを変更すると、EF は変更内容を見つけることができません。変更された各エンティティまたは関係の状態を手動で設定する必要があります。Attachグラフ全体をUnchanged状態ChangeObjectStateにし、グラフ内の単一のエンティティのみに影響を与えます。

最も簡単な方法は、保存中にグラフ全体を再度読み込み、変更を添付されたグラフに手動でマージすることであることがわかりました。特に、いくつかの関係/エンティティを削除したり、多対多の関係で複雑な操作を行いたい場合、これは便利です.

于 2011-08-04T08:19:37.503 に答える