Почему 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;
Ответы
Ответ 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
.
- Откройте .edmx (диаграмма)
- Нажмите F4, чтобы открыть свойства
- Установите
Lazy Loading Enabled
на false
- Сохранить и восстановить