Как избежать сохранения объектов в LINQ - PullRequest
4 голосов
/ 08 ноября 2010

Для моего объекта LINQ Foo я хочу иметь состояние «до и после», заключающее в скобки мою мутацию объекта (исходя из вызова ASP.NET MVC UpdateModel (), как это происходит). Моя идея состояла в том, чтобы скопировать свойства пре-мутации из прикрепленного экземпляра в новый неприкрепленный экземпляр. Тогда я смогу сделать обновления в прикрепленном экземпляре и сравнить их значения со значениями в неприсоединенном экземпляре. Вот так:

Foo real = context.Foos.First(aFoo => aFoo.ID == id)
Foo old = new Foo();
old.Bar = real.Bar;
old.Baz = real.Baz;
SomeSortOfUpdate(real);
if ( !real.Bar.Equals(old.Bar) || real.Baz.Equals(old.Baz) ) {
   LogChanges(old, real);
}
context.SubmitChanges();

Вот проблема: объект, на который ссылается «Foo old», сохраняется (вставляется) во время context.SubmitChanges(). Я проследил это до назначения свойств, которые были ассоциациями LINQ-to-SQL.

Так, например, если бы Baz был сгенерированным L2S типом с табличной поддержкой, включая old.Baz = real.Baz, это привело бы к вставке SQL для old в дополнение к любому обновлению SQL для real. Удаление этого (но сохраняющего old.Bar) заставляет вещи работать, как я ожидаю.

Я предполагаю, что это потому, что назначение Foo.Baz создает связь между Foo и Baz в графе сохраняемых объектов. Поскольку real сохраняется, LINQ также обходит все связанные объекты и ищет изменения. real.Baz сам по себе не изменен, но у него есть новая связь с old, которая еще не сохранена и, таким образом, попадает в вызов SubmitChanges.

Есть ли способ предотвратить сохранение объектов на графике?

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

Ваш анализ верен.Ваши задания устанавливают ссылки.

Вы можете изменить сгенерированный код, чтобы не делать этого (или написать свой).Но это означает, что вы должны жить без автоматически генерируемых классов сущностей.Я лично считаю это неприемлемым.

Почему бы вам не сериализовать объект перед изображением в словарь?Или скопировать значения его свойств в собственный класс DTO?

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

DataContext.GetTable<T>().GetModifiedMembers(entity)
0 голосов
/ 08 ноября 2010

Интересно, что бы это сделало

 var old = (Foo)real;

Мне интересно, создает ли сам экземпляр соединение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...