EntityFramework, Unit of Work — Отслеживание изменений пользовательских данных и их отправка через WebService

У нас есть единица работы, реализованная в EntityFramework, поэтому, когда мы используем ObjectContext и вносим какие-либо изменения в сущность, она отслеживается, а затем при сохранении изменений все это отражается в базовой базе данных.

Но что, если я хочу отслеживать изменения для своего пользовательского класса, чтобы все изменения отслеживались и отправлялись через вызов веб-сервиса?

У меня есть веб-сервис, который предоставляет мне некоторые данные, эти данные отображаются в сетке данных, а затем могут быть изменены. Я хочу отслеживать все изменения, а затем иметь возможность отправлять обратно через веб-сервис только те данные, которые были изменены. Есть ли какое-либо решение для этого, например EntityFramework или POCO или что-то еще? Или мне нужно реализовать для него свой собственный шаблон Unit of Work?


person kkris1983    schedule 07.07.2011    source источник


Ответы (2)


Отслеживание изменений работает только тогда, когда сущность присоединена к контексту. Существует особый тип сущностей, который называется Самоотслеживающие сущности, который может отслеживать изменения на стороне клиента при предоставлении веб-службы, но эти классы по-прежнему являются вашими основными объектами (а не пользовательскими объектами), и они применяют свое отслеживаемое состояние непосредственно к контексту.

То, что вы описываете, не имеет ничего общего с шаблоном единицы работы. Вы ищете шаблон набора изменений, который может передать сервису только различия. Реализация таких классов полностью зависит от вас. .NET их не предоставляет. .NET предлагает две реализации шаблона набора изменений.

  • упомянутые объекты самоотслеживания для EF
  • DataSet и связанные классы

Обе эти реализации по умолчанию передают все данные (причем как минимум DataSets имеют по умолчанию и старое, и новое состояние в сообщении). И наборы данных, и STE имеют одинаковые ограничения: они очень плохо совместимы.

person Ladislav Mrnka    schedule 08.07.2011

Отслеживание изменений на уровне свойств не следует оставлять на усмотрение клиента вызова WCF по целому ряду причин. Если вы используете шаблон DTO (объект передачи данных), вы должны иметь возможность сохранять свои отдельные объекты достаточно маленькими, чтобы избежать каких-либо значительных накладных расходов при отправке всего измененного объекта по сети. Затем на стороне сервера вы загружаете текущую версию объекта из своей базы данных, устанавливаете значения, предоставленные DTO, и позволяете Entity Framework отслеживать измененные свойства.

public SavePerson(Person person)
{
    using(var context = _contextFactory.Get())
    {
        var persistentPerson = context.People.Single(p => p.PersonId == person.PersonId);
        persistendPerson.FirstName = person.FirstName;
        /// etc. (This could be done with a tool like AutoMapper)
        context.SaveChanges();
    }
}

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

Надеюсь, это поможет.

person StriplingWarrior    schedule 07.07.2011
comment
Если вы изменяете несколько объектов на стороне клиента и хотите отслеживать, какие из них были изменены пользователем, вы можете поручить клиенту отслеживать измененные объекты и отправлять только эти объекты в Интернет. обслуживание оптом. И это был мой вопрос, как клиент может нести ответственность за отслеживание объектов, которые были изменены надлежащим образом с помощью хороших методов кодирования? Я подумал о реализации единицы работы, которая отправляет измененные данные по сети при вызове Save(). Это решение? - person kkris1983; 08.07.2011
comment
@ kkris1983: То, как был сформулирован вопрос, звучало так, как будто вы хотели, чтобы ваш контекст EF пытался продолжать отслеживать изменения, сделанные на стороне клиента. Способ отслеживания изменений на стороне клиента больше зависит от вашей клиентской среды, чем от EF/WCF. Например, если вы разрешаете сущности как объекты Javascript, вы можете легко добавить свойство IsChanged = true к каждому изменяемому объекту. Если вы используете Silverlight, вы можете использовать словарь для отслеживания каждого измененного объекта. - person StriplingWarrior; 08.07.2011
comment
Проблема с сохранением изменений в словаре или любой другой коллекции заключается в том, что из WebService я получаю составной объект, который имеет коллекции объектов, содержащих коллекцию других типов объектов. Поэтому, если в самый глубокий объект внесены какие-либо изменения, все объекты в цепочке к содержащему объекту должны быть помечены как грязные, а после редактирования все должно быть передано в качестве параметра вызову метода веб-сервиса. Как отследить такую ​​цепочку изменений? - person kkris1983; 10.07.2011