#entity-framework-4 #ef-code-first #entity-framework-4.1
#entity-framework-4 #ef-code-first #entity-framework-4.1
Вопрос:
Оказывает ли virtual
ключевое слово какой-либо эффект при использовании в свойствах в EF Code First?. Может ли кто-нибудь описать все его последствия в различных ситуациях?
Например, я знаю, что оно может контролировать отложенную загрузку — если вы используете ключевое слово virtual в свойстве ICollection / отношения «один ко многим», оно будет загружено с задержкой по умолчанию, тогда как если вы не используете ключевое слово virtual, оно будет загружено с нетерпением.
Какие еще эффекты может virtual
иметь ключевое слово в EF с объектами POCO?. Должен ли я сделать его используемым по умолчанию virtual
для всех моих свойств или по умолчанию его не использовать?
Ответ №1:
Пока что я знаю об этих эффектах.
- Отложенная загрузка: любые
virtual
ICollections будут загружаться отложенно, если вы специально не пометите их иначе. -
Более эффективное отслеживание изменений. Если вы удовлетворяете всем следующим требованиям, то для отслеживания изменений можно использовать более эффективный метод путем привязки ваших виртуальных свойств. По ссылке:
Чтобы получить прокси для отслеживания изменений, основное правило заключается в том, что ваш класс должен быть общедоступным, неабстрактным или не запечатанным. Ваш класс также должен реализовывать общедоступные виртуальные средства получения / установки для всех свойств, которые сохраняются. Наконец, вы должны объявить свойства навигации по отношениям на основе коллекции как
ICollection<T>
only. Они не могут быть конкретной реализацией или другим интерфейсом, производным отICollection<T>
(отличие от прокси с отложенной загрузкой)
Еще одна полезная ссылка, описывающая это, — это требования MSDN к созданию прокси-серверов POCO.
Комментарии:
1. Нет другой причины делать свойства виртуальными. Свойства навигации помечены как виртуальные для отложенной загрузки, а скалярные свойства — как виртуальные для отслеживания изменений.
2. что такое навигационные свойства и что такое скалярные свойства?
3. @AbidAli: Я полагаю, что свойство навигации — это внешний ключ (тип класса сущности) или отношение «один ко многим» (типа ICollection<>). Скалярное свойство — это базовый тип (int, string, ..) или complexType (который является просто структурой базовых типов).
4. Является ли »
public virtual byte[] bigData { get; set; }
» отложенной загрузкой?5. байты [] будут загружены быстро, только внешние ключи могут быть отложены. Если вы не хотите извлекать этот столбец, никогда не извлекайте всю запись целиком — просто
.Select(a=>new { fields you want })
.
Ответ №2:
Это виртуальное ключевое слово связано с темой загрузки данных из entity framework (отложенная загрузка, быстрая загрузка и явная загрузка).
Вам следует использовать ключевое слово virtual, когда вы хотите загрузить данные с отложенной загрузкой.
отложенная загрузка — это процесс, при котором объект или коллекция объектов автоматически загружается из базы данных при первом обращении к ней.
Например, при использовании класса сущности Blog, определенного ниже, связанные записи будут загружены при первом обращении к свойству навигации Posts:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
Отложенную загрузку коллекции Posts можно отключить, сделав свойство Posts невиртуальным.
если отложенная загрузка отключена, загрузка коллекции Posts все еще может быть достигнута с помощью быстрой загрузки (используя метод Include) или явной загрузки связанных объектов (используя метод Load).
Быстрая загрузка:
using (var context = new BloggingContext())
{
// Load all blogs and related posts
var blogs1 = context.Blogs
.Include(b => b.Posts)
.ToList();
}
Явная загрузка:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
// Load the posts related to a given blog
context.Entry(blog).Collection(p => p.Posts).Load();
}
Комментарии:
1. Как избежать проблемы N 1 при использовании virtual (отложенная загрузка)? Например, контекст. Блоги. ToList(); тогда он не будет объединять таблицы, а будет выполнять запрос select столько, сколько блогов.
2. @Expertwannabe Даже если вы используете отложенную загрузку, вы все равно можете явно запросить ускоренную загрузку с помощью вызова
Include()
.