Работа с прокси-серверами
При создании экземпляров типов сущностей POCO Entity Framework часто создает экземпляры динамически созданного производного типа, который выступает в качестве прокси-сервера для сущности. Этот прокси переопределяет некоторые виртуальные свойства сущности, чтобы вставить перехватчики для выполнения действий автоматически при доступе к свойству. Например, этот механизм используется для поддержки отложенной загрузки связей. Методы, представленные в этом разделе, также применимы к моделям, созданным с помощью Code First и конструктора EF.
Отключение создания прокси-сервера
Иногда полезно предотвратить создание экземпляров прокси-сервера Entity Framework. Например, сериализация экземпляров, не являющихся прокси-серверами, значительно упрощается, чем сериализация экземпляров прокси-сервера. Создание прокси-сервера можно отключить, очищая ProxyCreationEnabled
флаг. Одно место, где это можно сделать, находится в конструкторе контекста. Например:
public class BloggingContext : DbContext
{
public BloggingContext()
{
this.Configuration.ProxyCreationEnabled = false;
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
Обратите внимание, что EF не будет создавать прокси-серверы для типов, где нет ничего для прокси-сервера. Это означает, что вы также можете избежать прокси-серверов, имея типы, которые запечатаны и (или) не имеют виртуальных свойств.
Явное создание экземпляра прокси-сервера
Экземпляр прокси-сервера не будет создан, если вы создаете экземпляр сущности с помощью нового оператора. Это может не быть проблемой, но если вам нужно создать экземпляр прокси-сервера (например, чтобы отложенная загрузка или отслеживание изменений прокси-сервера работали), то это можно сделать с помощью Create
метода DbSet
. Например:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Create();
}
Универсальная версия Create
может использоваться, если требуется создать экземпляр производного типа сущности. Например:
using (var context = new BloggingContext())
{
var admin = context.Users.Create<Administrator>();
}
Обратите внимание, что Create
метод не добавляет или присоединяет созданную сущность к контексту.
Обратите внимание, что Create
метод просто создаст экземпляр самого типа сущности, если при создании прокси-типа для сущности не будет значения, так как он ничего не сделает. Например, если тип сущности запечатан и (или) не имеет виртуальных свойств, Create
то просто создаст экземпляр типа сущности.
Получение фактического типа сущности из типа прокси-сервера
Типы прокси-сервера имеют имена, которые выглядят примерно так:
System.Data.Entity.DynamicProxies.Blog_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6
Тип сущности для этого типа прокси-сервера можно найти с помощью GetObjectType
метода ObjectContext
. Например:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
var entityType = ObjectContext.GetObjectType(blog.GetType());
}
Обратите внимание, что если переданный GetObjectType
тип является экземпляром типа сущности, который не является типом прокси,то тип сущности по-прежнему возвращается. Это означает, что этот метод всегда можно использовать для получения фактического типа сущности без каких-либо других проверка, чтобы узнать, является ли тип прокси-сервера или нет.