Сериализация объектов платформы Entity с отношением «один к большому»

Я пытаюсь использовать EF с Code First и Web API. У меня нет никаких проблем, пока я не перейду к сериализации отношений «многие-ко-многим». Когда я пытаюсь выполнить следующий метод web api ниже, я получаю следующее сообщение об ошибке:

public class TagsController : ApiController { private BlogDataContext db = new BlogDataContext(); // GET api/Tags public IEnumerable GetTags() { return db.Tags.AsEnumerable(); } } 

Я получаю следующую ошибку:

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

Я прочитал некоторые статьи SO ( статья 1 , статья 2 ), что исправление заключается в добавлении следующего атрибута:

[DataContract (IsReference = true)]

но это не имело никакого эффекта. Также использование [IgnoreDataMember] не имеет эффекта. Единственный вариант, который, похоже, работает, – установить для параметра Configuration.ProxyCreationEnabled значение false. Это мой единственный вариант? Я что-то упускаю?

Примеры объектов POCO:

Тег

 [DataContract(IsReference = true)] public class Tag { public Tag() { this.Blogs = new HashSet(); } [Key] [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [IgnoreDataMember] public virtual ICollection Blogs { get; set; } } 

Блог

 [DataContract(IsReference = true)] public class Blog { public Blog() { this.Tags = new HashSet(); } [Key] [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [IgnoreDataMember] public virtual ICollection Tags { get; set; } } 

Когда вы увидите такой объект, как:

System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D

Это исполняемая версия EF, созданная для прокси-сервера, которая обычно считается объектом POCO.

Entity Framework создал этот объект, потому что он отслеживает, когда объекты изменились, поэтому, когда вы вызываете .SaveChanges() он может оптимизировать, что делать. Падение этого состоит в том, что вы фактически не используете определенный объект, который вы определили, поэтому Data Contracts and Frameworks (Json.net) не могут использовать их, поскольку они будут использовать ваш оригинальный объект POCO.

Чтобы предотвратить возврат EF из объекта, у вас есть два варианта (ATM):

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

 DbContext.Configuration.ProxyCreationEnabled = false; 

Это полностью отключит создание объектов Proxy для каждого запроса для конкретного DbContext. (Это не влияет на кешированный объект в ObjectContext).

Во-вторых, используйте EntityFramework 5.0+ с AsNoTracking () (ProxyCreationEnabled по-прежнему доступен в EF 5.0)

Вы также должны иметь возможность

 DbContext.Persons.AsNoTracking().FirstOrDefault(); 

или

 DbContext.Persons. .Include(i => i.Parents) .AsNoTracking() .FirstOrDefault(); 

Вместо того, чтобы глобально отключать создание прокси для DbContext, это только отключает его для каждого запроса. (Это влияет на кешированный объект в ObjectContext, он не кэшируется)

Я хотел оставить бездействие прокси-сервера и обнаружил, что использование ProxyDataContractResolver похоже, решило проблему для меня. См. Msdn для справки о том, как использовать его в wcf, что не является точно WebAPI, но должно заставить вас идти по правильному пути.

 db.Configuration.ProxyCreationEnabled = false; 

решит вашу проблему

  • Определение нескольких внешних ключей для одной и той же таблицы в корневом коде Entity First
  • linq для объектов не распознает метод
  • Как выполнить запрос «in» в структуре сущностей?
  • Установка таймаута базы данных в Entity Framework
  • Entity Framework 4.2 exec sp_executesql не использует индексы (sniffing параметров)
  • Как добавить ROW_NUMBER в запрос LINQ или Entity?
  • Сообщение об ошибке «Невозможно загрузить один или несколько запрошенных типов. Получите свойство LoaderExceptions для получения дополнительной информации. '
  • Лётная загрузка против желаемой загрузки
  • Свойство «имя» является частью ключевой информации объекта и не может быть изменено. Основы Entity Framework
  • Структура Entity PostgreSQL
  • «Тип узла выражения LINQ« Invoke »не поддерживается в LINQ to Entities» - тупик!
  • Interesting Posts

    Как я могу запустить программный экран приложений Android?

    Потерял все данные в Windows XP после синего экрана

    как экспортировать (JUnit) набор тестов как исполняемый банку

    Могу ли я перенести лицензию Windows 8 на мой ноутбук на мой рабочий стол?

    Получение телефонного кода в США с помощью Android

    Устройство не обнаружено в Eclipse при подключении к USB-кабелю

    Неверный доступ к файлу базы данных Data Access

    Ошибка Maven «Ошибка передачи …»

    Как назначить номера мониторов в Windows 7

    При использовании заголовков C в C ++ следует ли использовать функции из std :: или глобального пространства имен?

    Почему мой браузер выводит меня на сайт WRONG?

    Как удаленно проверять офисную версию?

    Bootstrap 3 Карусель увядает с новым слайдом, а не сползает на новый слайд

    Как программно отправлять запрос POST на страницу JSF без использования HTML-формы?

    Обновление Studio Studio Gradle до версии 0.5.0 – Gradle Migrating От 0,8 до 0,9 – Также обновление для Android Studio до 0.8.1

    Давайте будем гением компьютера.