2012-02-29 3 views
23

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

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

Мой код не работает в этой строке. Все мои 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; 

ответ

38

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

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

Редактировать

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

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

Я добавил более подробно на мой вопрос. У меня был этот набор настроек, и мое приложение не может обрабатывать прокси, такие как POCO. –

+0

Его в обновленный вопрос. Я отражаю класс, чтобы получить от него атрибуты. –

+0

@ MalcolmO'Hare Я опубликовал код, который мы используем, чтобы получить тип POCO из прокси-типа. – cadrell0

2

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

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

+0

На каждой итерации моей программы (ее опрос базы данных, когда запись вставленная работает на другую базе данных) создать новый контекст и загрузить все мои данные в память. Когда вся моя работа выполняется, все загруженные данные + контекст удаляется. Если я дважды запускаю один и тот же экспорт, второй раз, когда он запускает некоторые записи, возвращается как прокси-серверы, которые не выполнялись при первом запуске. Также я теперь использую 4.3 (обновлен, чтобы проверить, исправлена ​​ли эта проблема). –

+0

Да, звучит странно, что на основе этого вы получите прокси-объект. Однако вы можете установить NoTracking только для исключения кеша. –

+1

@ MalcolmO'Hare Являются ли прокси виртуальными свойствами других объектов? Возможно, вы просто видите EF ленивую загрузку. Если вы не используете (загружать) объект, настроенный как виртуальный, он может отображаться как прокси. –

6

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

_dbContext.Configuration.ProxyCreationEnabled = false; 

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

1

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

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

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

От MSDN

+2

Он хочет, чтобы фактическая сущность, а не ее тип. – Tito

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