2013-09-27 3 views
2

Я разрабатываю приложение последние пять месяцев и просто столкнулся с этой проблемой.Неоткрытые требования класса POCO

Мы используем EF5 и, подобно this question, я разработал иерархию классов, чтобы все классы сущностей были получены из абстрактного базового класса, чтобы принудительно реализовать интерфейсы проверки. Мы также используем атрибуты проверки в классах сущностей.

Все работает нормально, пока я не начал использовать классы сущностей в службах WCF. Я получаю кучу исключений в сериализации и пытаюсь выяснить, какое правило «POCO» я нарушил в дизайне. This article говорит мне, что класс (очевидно ...) не может быть абстрактным, но поскольку мои классы DERIVING из абстрактного класса, возможно, я нарушил правило, о котором я не знаю?

UPDATE: Вот исключение, которое я борюсь с:

System.Runtime.Serialization.SerializationException, mscorlib, Version = 4.0.0.0, культура = нейтральной, PublicKeyToken = b77a5c561934e089

Тип 'System.Data.Entity.DynamicProxies.WorkSession_63308485A9007DE087FF55AD9F246FD677863AA39AD56FEF4586AB87E21832DD' с данными название контракта 'WorkSession_63308485A9007DE087FF55AD9F246FD677863AA39AD56FEF4586AB87E21832DD: http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' не ожидается. Подумайте об использовании DataContractResolver или добавьте любые типы, не известные статически в список известных типов - например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, переданных DataContractSerializer.

+0

Опубликовать соответствующие сообщения об исключениях. И нет, это не имеет никакого отношения к абстрактным базовым классам. –

+0

Entity Framework динамически создает классы, которые производятся от вас, и эти динамически созданные классы не предназначены для сериализации. Если вы можете жить с ограничениями использования только тех классов, которые были определены вами, вы можете пометить свои классы как «запечатанные» (изменить: [или установить «ProxyCreationEnabled» на false] (http://stackoverflow.com/ a/7277885/743382)), но это означает отсутствие отслеживания изменений, отсутствие ленивой загрузки и т. д., поскольку эти функции реализованы путем переопределения методов на ваших классах. – hvd

+0

Возможный дубликат [Сериализуемые классы и динамические прокси в EF - как?] (Http://stackoverflow.com/questions/7276507/serializable-classes-and-dynamic-proxies-in-ef-how) – hvd

ответ

2

Поскольку ваши POCO используют ленивую загрузку, вы не получаете фактических типов из EF, а скорее прокси, чтобы свойства навигации были автоматически реализованы для ленивой загрузки.

Мой совет заключается в том, чтобы забыть идею разоблачения объектов домена из веб-служб. Бьюсь об заклад, будут ответы, которые помогут вам убедить вас, что это возможно в этом конкретном случае с кучей дополнительных заклинаний. Тем не менее, самый безопасный подход заключается в том, чтобы переключить ваше мышление на DTOs, объекты передачи данных, шаблон, в котором вы создаете дополнительный слой классов «только для данных», которые легки и безопасны для сериализации и передачи по кабелю.

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

+0

Я начал работу DTO, но потом подумал, что я могу спасти нас, имея кучу дополнительных параллельных классов, но, похоже, у меня нет выбора. Спасибо за ответ! –

+0

Мы не можем добавлять новые инструменты в этот момент (процесс утверждения и т. д.), и количество сущностей, которые нам нужны для поддержки, ограничено для первого выпуска, поэтому я написал набор классов DTO, и мы будем рады! Спасибо! –

1

Вы не нарушили правило «POCO». «Динамический прокси», упомянутый в исключении, - это класс, который является , производным от вашего объекта WorkSession, но он не выводится в вашем коде, а динамически во время выполнения. Entity Framework делает это - по умолчанию - позволяет делать ленивую загрузку и динамическое отслеживание изменений, если вы отметили свои свойства навигации (а может быть, и скалярные свойства) как virtual.

Вы должны отключить создание динамического прокси, когда вы планируете сериализовать объект с WCF. Вы можете сделать это, просто установив флаг на контексте , прежде чем вы загружать объекты из базы данных:

context.Configuration.ProxyCreationEnabled = false; 

var worksessions = context.WorkSessions.....ToList(); 

Загруженный worksessions являются реальным типа исполнения WorkSession сейчас, а не динамического типа прокси и WCF больше не должен жаловаться.

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