Как я могу создать отдельный клон класса EF codefirst для тестирования? - PullRequest
3 голосов
/ 08 апреля 2011

Я хочу создать интеграционный тест, который извлекает сущность EF из БД, клонирует ее в отдельный объект, изменяет ее, а затем сохраняет ее и сравнивает снова с оригиналом.

Однако яиспользовал AutoMapper для создания клона класса, но оказывается, что это также отслеживается или псевдоним исходного объекта.Мне нужно, чтобы он был полностью отсоединен от EF, и я могу делать это вне моего класса репозитория (т.е. не использовать никаких методов отсоединения EF).

Причина, по которой это происходит, заключается в том, что мой класс EF содержит вложенные коллекциидругие классы и EF не обрабатывают сохранение всего дерева объектов.Следовательно, мой метод Update () в моем классе репозитория обрабатывает это, и я хочу, чтобы мой тест NUnit проверил этот код.Я хочу, чтобы тест позволил быстро создать копию моего исходного класса без отслеживания EF.

Ответы [ 3 ]

6 голосов
/ 17 ноября 2011

Создание клонированного объекта, содержащего текущие, исходные значения или значения базы данных. Объект DbPropertyValues, возвращаемый из CurrentValues, OriginalValues ​​или GetDatabaseValues, можно использовать для создания клона сущности.Этот клон будет содержать значения свойств из объекта DbPropertyValues, использованного для его создания.Например:

using (var context = new UnicornsContext())
{
    var unicorn = context.Unicorns.Find(1);

    var clonedUnicorn = context.Entry(unicorn).GetDatabaseValues().ToObject();
}

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

Клонированный объект может быть полезен для решения проблем, связанных с одновременным обновлением базы данных, особенно когда пользовательский интерфейс включает привязку данных к объектам определенного объекта.тип используется.(См. Часть 9 для более подробной информации о работе с оптимистичным параллелизмом.)

* От http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx

Надеюсь, что это может помочь другим

3 голосов
/ 23 октября 2013

Все проблемы исчезли, когда вы используете EF 5+, где они представили метод AsNoTracking () . Строка ниже возвращает несвязанный экземпляр, поэтому весь контекст не будет знать о каких-либо изменениях в этом экземпляре:

context.Clients.AsNoTracking().FirstOrDefault(item => item.Id == id);

Если Клиенты имеют ссылку на Адрес , и вам тоже нужен несвязанный экземпляр, просто используйте Включить :

context.Clients
       .Include("Address").AsNoTracking()
       .FirstOrDefault(item => item.Id == id);
0 голосов
/ 10 апреля 2011

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

Один из способов сделать копию класса - использовать сериализацию, которая по умолчанию сохраняет только открытые поля (сериализация Xml или сериализация DataContract). Сериализация объекта и десериализация его обратно в новый экземпляр. Сериализация сохранит весь граф объектов, а десериализованный граф объектов будет отсоединен. Просто учтите, что этим сериализациям не нравятся циклические ссылки в графе объектов (свойство навигации от A до B и от B до A от циклов). Сериализация также слишком агрессивна, поэтому она может проходить по графику более глубоко, чем вы хотите - это может быть особенно опасно во многих отношениях.

Наилучшим подходом является использование интерфейса ICloneable и реализация Clone или определение методов поддержки, которые будут выполнять различные клоны с необходимой глубиной.

Здесь - это другой подход для клонирования EntityObject сущностей. Это сложный код, особенно часть с Reflection.Emit. Но это не поможет вам, потому что сначала используется код POCO.

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