2009-08-19 2 views
3

Я столкнулся с сценарием, в котором мне по существу нужно записать изменения дочернего объекта связи «один ко многим» в базу данных, но не сохранять изменения, внесенные в родительский объект.Сохранение единственной сущности вместо всего контекста

В настоящее время инфраструктура Entity Framework работает с базами данных в контексте контекста (EntityContext.SaveChanges()), что имеет смысл для обеспечения соблюдения отношений и т. Д. Но мне интересно, есть ли какая-то передовая практика или, возможно, рекомендуемый способ продолжайте делать мелкозернистую базу данных, которая связывается с отдельными людьми, а не с целым контекстом.

+1

Я не видел способа сделать это до сих пор ... и это, вероятно, правильно. То, что вы ищете, может привести к несогласованности данных. – ADB

ответ

7

Лучшие практики? Вы имеете в виду, кроме того, «Не делайте этого!»?

Я не думаю, что существует лучшая практика для создания объекта ObjectContext, отличного от состояния базы данных.

Если вы должны это сделать, я бы предложил новый объект ObjectContext и внеся изменения в дочерний объект. Таким образом, оба контекста согласованы.

+2

Использование отдельного контекста - хороший способ сделать это. Процесс в основном: 1) Создайте еще один объект ObjectContext и присоедините прикрепленный к нему дочерний объект. 2) Установите EntityKey родительского свойства навигации. 3) Сохраните новый контекст, а затем отсоедините его. 4) Прикрепите дочерний элемент к основному контексту. – dkr88

2

Это можно сделать с помощью AcceptAllChanges().

Внесите изменения в родительский объект, вызовите AcceptAllChanges(), затем внесите изменения в связанные объекты и вызовите SaveChanges(). Изменения, внесенные вами в родительский элемент, не будут сохранены, поскольку они были «привязаны» к объекту, но не сохранены в базе данных.

using (AdventureWorksEntities adv = new AdventureWorksEntities()) 
{ 
    var completeHeader = (from o in adv.SalesOrderHeader.Include("SalesOrderDetail") 
          where o.DueDate > System.DateTime.Now 
          select o).First(); 
    completeHeader.ShipDate = System.DateTime.Now; 
    adv.AcceptAllChanges(); 
    var details = completeHeader.SalesOrderDetail.Where(x => x.UnitPrice > 10.0m); 
    foreach (SalesOrderDetail d in details) 
    { 
      d.UnitPriceDiscount += 5.0m;  
    } 
      adv.SaveChanges(); 
} 
+1

Делает смысл - но тогда, если мне все еще нужно отслеживать, а затем комментировать изменения в родительском объекте, я потеряю возможность сделать это после выполнения AcceptAllChanges() (правильно?) – dkr88

4

У меня такая же потребность. Решение, которое я рассматриваю, заключается в реализации свойств оболочки для всех объектов, которые сохраняют любые изменения свойств в частном порядке, не затрагивая фактическое свойство объекта. Затем я добавляю метод SaveChanges() к сущности, которая будет записывать изменения в объект, а затем вызывает SaveChanges() в контексте.

Проблема с этим подходом заключается в том, что вам необходимо сделать все ваши сущности соответствующими этому шаблону. Но, похоже, это работает очень хорошо. У этого есть другой недостаток в том, что, если вы вносите много изменений в множество объектов с большим количеством данных, вы получаете посторонние копии в памяти.

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

Смежные вопросы