2016-11-18 5 views
0

Я стараюсь держать это как можно коротким:EF6: Установка DataSource DataGridView в EF-Entity приводит к загрузке его дочерних элементов. Зачем?

У меня есть простая база данных с некоторыми таблицами: исполнителей, альбомов, песен.

  1. У художников может быть несколько альбомов. альбомы могут быть созданы несколькими художниками (многие-ко-многим).
  2. альбомы могут иметь несколько композиций, но одна песня ограничена одним альбомом (1-ко-многим).

EntityFramework помещает эти таблицы в классы просто отлично. Теперь я связывание моего DbContext экземпляра к DataGridView в Windows Forms # проекта C:

DBEntities db = new DBEntities(); 
db.Artists.Include(a => a.Albums).Load(); // include children albums as well 
artistBindingSource.DataSource = db.Artists.Local.ToBindingList(); 

Экземпляра DataGridView отображает содержимое правильно. Я могу сохранить изменения и т. П.

Если пользователь нажимает на ячейку (с именем художника) в DataGridView, я загрузке связанных альбомов путем присвоения второй DataGridView (с albumBindingSource) в коллекции альбомов художника:

Artist a = (Artist)row.DataBoundItem; // row contains selected grid row 
if (a != null) 
{ 
    albumBindingSource.DataSource = a.Albums; 
} 

Этом также работает нормально, но при отладке операторов SQL я нашел что-то своеобразное: При назначении второго DataSource DataGridView для a.albums (это альбомы выбранного экземпляра) Entity Framework также лениво загружает песни альбома в несколько операторов SELECT (один для каждая песня).

Вопрос 1: Почему он загружает детей альбомов? Я никогда не говорил это делать.


Однако: если добавить следующий код в строку, где предварительно загруженная сущность, ленивая нагрузка исчезает:

db.Artists.Include(c => c.Albums.Select(b => b.Songs)).Load(); 

Вопрос 2: ли мне действительно нужно поджать все ребенок и внуков во избежание ленивой загрузки? Я никогда не хотел, чтобы внуки появлялись в моей Windows-форме.

Вопрос 3: (см. Q.2) Почему он «включает», а затем «выбирает»? Я думаю, что-то вроде ...

db.Artists.Include(c => c.Albums.Include(d => d.Songs)).Load(); 

... было бы более интуитивно понятным.

В любом случае: спасибо, что помогли мне здесь!

ответ

0

Загружается объекты, вероятно, потому что LazyLoading включен. Вы можете превратить команду LazyLoadingdb.Configuration.LazyLoadingEnabled = false; не нужно загружать все содержимое. Кроме того, существует два метода Include (не считая перегрузки). Один из них - метод DbQuery<TEntity>, а DbSet<TEntity> наследует его, поэтому вы можете увидеть метод Include для ваших наборов, другой - в классе QuerableExtensions, который является методом расширения IQuerable<T>, который в пространстве имен System.Data.Entity.Так написано для IQuerable, и вы указываете коллекции детей, используя метод Select.

+0

Спасибо Адиль, что сделал трюк. Но есть одна вещь, которую я до сих пор не могу понять: если я вызываю только db.Artists.Load(); в начале, никакой ленивой загрузки не делается. Оператор SELECT содержит только таблицу художников. Но если я привяжу второй DataGridView к a. Альбомам, ленивая загрузка выполняется автоматически. – AudioGuy

+0

@AudioGuy, я рад, что если сработает. что вы не можете понять? –

+0

Извините, мой первый комментарий был отправлен слишком рано ;-) – AudioGuy