Подтвердить что ты не робот

Почему EF возвращает прокси-класс вместо фактического объекта?

У меня возникают проблемы с возвратом сущностей Framework Proxies, когда я хочу, чтобы фактический класс сущности. В первый раз, когда я запускаю свой код, все работает правильно (без прокси), но каждая итерация впоследствии один из моих DbSets всегда возвращает прокси вместо фактического типа.

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

Мой код не работает в этой строке. Все мои POCOs имеют набор атрибутов Table, но поскольку он возвращает прокси-класс, атрибут таблицы отсутствует.

TableAttribute attrib = (TableAttribute)attributes.Single();

Есть ли за кулисами статическая магия в DbContext, которая живет после уничтожения объекта?

Я переношу свои объекты в память, используя следующие

MajorClasses = ctx.MajorClasses.ToArray();

Я также пробовал

MajorClasses = ctx.MajorClasses.AsNoTracking().ToArray();

В моем OnModelCreating у меня есть следующий набор

base.Configuration.ProxyCreationEnabled = false;
            base.Configuration.LazyLoadingEnabled = false;
4b9b3361

Ответ 1

Вы можете установить ObjectContext.ContextOptions.ProxyCreationEnabled в значение false. Это не позволит вам использовать некоторые необычные функции EF, такие как ленивая загрузка, и я считаю, что отслеживание изменений.

Что касается вашего приложения, он должен иметь возможность обращаться с прокси-серверами так же, как и те типы, которые они представляют. Есть ли конкретная проблема, с которой вы сталкиваетесь?

Edit

У нас есть код, для которого требуется тип POCO вместо прокси-типа, и мы делаем следующее, чтобы определить, является ли текущий тип прокси-сервером.

if (entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies")
{
    entityType = entityType.BaseType;
}

Ответ 2

Чтобы отключить создание прокси в Entity Framework 5, вы можете использовать следующее:

_dbContext.Configuration.ProxyCreationEnabled = false;

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

Ответ 3

По умолчанию EF использует "Отслеживание изменений" и использует кеш в памяти всех объектов. При работе с EF вы можете использовать различные параметры слияния. По умолчанию EF 4.1 установлен в AppendOnly Merge Option. Насколько я понимаю, это означает, что если вы уже запросили сущность, последующие запросы получат сущность из кеша (если в базе данных не обнаружены изменения). Таким образом, вы можете увидеть, как возвращается кэшированная сущность.

В EF 4.1 вы можете использовать опцию NoTracking Merge Option. Это пойдет в базу данных для каждого вызова.

Ответ 4

В EF 6.1.3 вы можете получить правильный тип, используя

using (var context = new BloggingContext()) { 
    var blog = context.Blogs.Find(1); 
    var entityType = ObjectContext.GetObjectType(blog.GetType()); 
}

Обратите внимание, что если тип, переданный в GetObjectType, является экземпляром типа сущности, который не является прокси-типом, тип объекта все еще возвращается. Это означает, что вы всегда можете использовать этот метод для получения фактического типа сущности без какой-либо другой проверки, чтобы узнать, является ли тип прокси-типом или нет.

От MSDN

Ответ 5

простое решение - вы пропускаете какой-то объект, который должен быть включен, а также делаете это до получения значений

_dbContext.Configuration.ProxyCreationEnabled = false;

Ответ 6

В моем случае эта проблема была исправлена установкой Lazy Loading Enabled на false.

  1. Откройте .edmx (диаграмма)
  2. Нажмите F4, чтобы открыть свойства
  3. Установите Lazy Loading Enabled на false
  4. Сохранить и восстановить