Entity Framework-Включить / Ссылка / Коллекция
Мне было интересно, почему существуют отдельные методы для заполнения навигационных свойств.
Если я работаю со всем набором, я могу вызвать Include либо для свойства, либо для коллекции.
Однако, если я работаю с одной сущностью, есть два отдельных метода для вызова в зависимости от того, является ли элемент коллекцией (
Collection) или одной ссылкой (Reference).Есть ли какой - нибудь способ обойти это-это делает вещи более сложными, чем я думаю, необходимо. И может ли кто-нибудь объяснить, почему это было решено во время проектирования эф?
EDIT
Если смотреть дальше, то проблема становится глубже. То, что я пытался сделать, - это создать универсальный способ загрузки свойств коллекции/навигации для одной сущности. Это можно сделать достаточно легко на всем наборе, используя Include. Но сигнатуры метода для
Reference и Collection немного отличаются.Неважно, придется разбрасывать эти звонки по всему моему приложению.
Например
dbSet<T>().Include(e => e.Property).Include(e => e.Collection).Include(e => e.Collection.Property)
Кажется, все работает.
Однако призывы к единой сущности различны:
context.Entry(entity).Reference(e => e.Property).Load();
context.Entry(entity).Reference(e => e.Property.Select(e => e.SubProperty)).Load();
context.Entry(entity).Collection(e => e.Collection).Load();
2 ответов:
Единственная цель метода
МетодInclude()состоит в явном стремлении загрузить связанные данные при запросе.
Entry(), с другой стороны, предназначен для предоставления вам конкретного контроля над текущим состоянием сущности, присоединенной к контексту, а не только над связанными даннымиLoad().Именно поэтому вы должны явно выбирать между
Collection,ReferenceиPropertyметоды, каждый из которых предоставляет различный набор функциональных возможностей (следовательно, возвращает различный тип), для пример:Тем не менее, если вы заинтересованы только в
Скаляр (
DbPropertyEntry) содержит свойствоIsModified, которое указывает, изменилось ли значение от " x " до " y " (например).Ссылка (
DbReferenceEntry) содержит свойствоIsLoaded, которое указывает, были ли данные уже загружены из базы данных (в отличие от записи свойства' Scalar').Коллекция ссылок (
DbCollectionEntry) производные отICollection(следовательно,IEnumberableТакже), которые означают, что вы можете повторять над ней-данные. тем не менее, он не может содержать СВОЙСТВОIsModified, поскольку оно может отличаться для каждого элемента в коллекции.Load(), Вы можете использовать полиморфный методMember()(который возвращаетDbMemberEntry, который является базовым классом для всех вышеперечисленных классов) и проверить, является ли запись "загружаемой":var memberEntry = this.Entry(entity).Member("NavigationProperty"); if (memberEntry is DbCollectionEntry) ((DbCollectionEntry)memberEntry).Load(); if (memberEntry is DbReferenceEntry) ((DbReferenceEntry)memberEntry).Load();
Вы можете сделать это следующим образом:
1.- Загрузить сущность, включая коллекции:
MyClass myObject = dbContext.MyClasses .Include(cls => cls.ObjectCollection) .Single(cls => cls.Pk == entityPk);2.- Затем вы должны получить эту запись объекта и сказать EF, чтобы загрузить необходимые свойства в объекты коллекции:
dbContext.Entry(myObject).Collection("ObjectCollection").Query().Include("ReferenceClass").Load();Дальнейшее чтение:
Http://msdn.microsoft.com/en-us/data/jj574232#explicitFilter
Comments