EF4 сохранить сложный отдельный объект графа - PullRequest
1 голос
/ 04 августа 2011

У меня есть следующая модель EF на основе EntityObject (свойства записаны здесь как поля для поддержания чистоты кода):

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.

Как я могу заставить это работать?

Ответы [ 2 ]

1 голос
/ 04 августа 2011

Ладислав прав.Тем не менее, есть еще один вариант, который вы должны рассмотреть, который решил бы эту проблему и все же позволил бы вам сохранить детализированную модель - POCO с самостоятельным отслеживанием.Существует шаблон T4 (он либо связан с VS2010, либо доступен для загрузки), который позволяет графу объектов отслеживать его состояние (включая добавление / удаление объектов на графике, а также то, какие свойства объекта были изменены), так чтоможет заново прикрепить график, внеся изменения;EF4 определит изменения и применит их к менеджеру состояния объекта.

1 голос
/ 04 августа 2011

Речь не идет об обновлении. Если вы измените график в отдельном состоянии, EF не сможет найти, какие изменения вы сделали. Вы должны вручную установить состояние каждого измененного объекта или отношения . Attach переведет весь граф в состояние Unchanged, а ChangeObjectState повлияет только на один объект в графе.

Вы обнаружили, что самый простой способ - снова загрузить весь график во время сохранения и вручную объединить внесенные изменения в прикрепленный график. Особенно, если вы хотите удалить некоторые отношения / сущности или выполнять сложные операции со многими отношениями ко многим, это будет удобно.

...