WCF RIA Services SP1, Entity Framework 4, обновление только измененных столбцов - PullRequest
1 голос
/ 13 июня 2011

Я использую класс LinqToEntitiesDomainService для обновления базы данных с помощью клиента Silverlight 4. Существует расширенный метод AttachAsModified для структуры объекта ObjectContext, который позволяет вам указывать исходные значения свойств объекта:

Order original = this.ChangeSet.GetOriginal(currentOrder);
this.ObjectContext.Orders.AttachAsModified(currentOrder, original);

По умолчанию службы WCF RIA не отправляют исходные значения на сервер, поэтому необходимо применить атрибут [RoundtripOriginal ()] к его сущности.

Однако, даже если я предоставлю исходные значения, SQL, сгенерированный платформой Entity, обновляет все столбцы, а не только измененные. Поскольку метод AttachAsModified () не является собственным методом класса ObjectContext (это расширенный метод, определенный в классе ObjectContextExtensions), я попытался использовать Метод ApplyOriginalValues, который определен в классе ObjectSet. Без изменений. Кажется, сущность 4.1, выпущенная недавно, может иметь решение (не уверен). Как насчет сущности 4? Возможно ли EF генерировать sql для обновления только измененных столбцов?

Ответы [ 3 ]

3 голосов
/ 13 июня 2011

AttachAsModified помечает объект как измененный.Впоследствии (цитата из MSDN):

Когда вы изменяете EntityState записи объекта сущности на Modified, все свойства объекта помечаются как измененные, независимо от текущих или исходных значений.

Предостережение;Я не сделал этого, но он должен работать.

Вместо использования AttachAsModified пометьте объект как UnChanged, используя метод ChangeState .

Затем используйте метод SetModifiedProperty для свойств, которые были изменены, чтобы включить их в обновление.

РЕДАКТИРОВАТЬ: Если вы хотите найти способ изменения свойств, существует парастатей, объясняющих, как это сделать с помощью ObjectStateManager , например this

1 голос
/ 01 июля 2011

Мне удалось сделать это, сначала прикрепив объект, а затем вызвав ApplyOriginalValues ​​для EntitySet. Вам понадобится объект с исходными значениями, чтобы сделать это. Этот способ также можно использовать для предотвращения обновления столбца, например, для защиты на уровне строк.

ПРИМЕЧАНИЕ. К сожалению, это не работает без предварительного извлечения исходного объекта из базы данных. В противном случае из обновления исключаются только свойства, для которых установлено значение по умолчанию ...

1 голос
/ 13 июня 2011

Я задавал аналогичный вопрос на форумах MSDN, и подтверждается, что службы WCF RIA изменят все столбцы.Альтернатива:

Вы можете получить копию из базы данных, сравнить и пометить SetModifiedProperty вручную, используя отражение.

// change state of entity as Unmodified/Unchanged...
original.EntityState = Unchanged;

// this is copy form database...
// Use different context
MyOrderContext context = new MyOrderContext();
Order dbOriginal = context.Orders.First( x=>x.OrderID == original.OrderID);

foreach(PropertyInfo p in copy.GetTypes().GetProperties()){
   Object originalValue = p.GetValue(dbOriginal);
   Object newValue = p.GetValue(original);
   if(originalValue!=null && newValue!=null 
       && originalValue.Equals(newValue)){
       continue;
   }
   // resetting this will 
   // make entity's only current
   // property as changed
   p.SetValue(original,originalValue);
   p.SetValue(original,newValue);
}

Возможно, вам придется изменить код в соответствии с ситуацией, проверьте, доступно ли свойство только для чтенияили нет, и это только пример, но он поможет вам развить его.

...