Играя с Entity Framework и NHibernate, используя сущности POCO, я сделал следующее наблюдение, которое я нахожу немного необычным:
У меня есть две сущности POCO, 'Order' и 'Product'.Между этими двумя есть отношения многие ко многим.Когда я добавляю товар в заказ, я использую метод FixUp, чтобы гарантировать, что противоположная сторона отношения также обновляется, т. Е. Что также обновляется коллекция товаров в «Заказах».
Мой заказУ объекта POCO есть следующий метод для выполнения FixUp:
private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach(Product p in e.NewItems)
{
p.Order.Add(this);
}
}
}
При профилировании этого сценария с помощью EFProf и NHProf я заметил, что Entity Framework генерирует еще один оператор SQL, чем NHibernate, причина которого кажетсябыть такой строкой:
p.Order.Add(this);
При использовании Entity Framework приведенная выше строка вызывает выполнение выбора в базе данных для возврата всех заказов на продукт 'p'.Я не ожидаю, что это произойдет, так как я использую ленивую загрузку и на самом деле не хочу получать доступ к коллекции продуктов Order.Я просто хочу добавить к нему заказ.
В NHibernate не делается никаких попыток загрузить набор заказов товаров, если я не пытаюсь получить к нему доступ явно.Например, если я скажу:
foreach(Order o in product.Orders)
{
Console.WriteLine(o.Id);
}
Итак, в конечном счете, мой вопрос: почему Entity Framework генерирует дополнительный оператор SQL?Есть ли разница в реализации отложенной загрузки для двух платформ, о которых я не знаю?
*** РЕДАКТИРОВАНИЕ В ОРИГИНАЛЕ Кажется, что Entity Framework не ведет себя лениво, когда в коллекции вызывается какой-либо метод.Любая попытка добавить или посчитать (или предположительно любую другую операцию над коллекцией) приводит к загрузке этой коллекции в память.
Что интересно, так это мое сопоставление NHibernate (которое представляет собой пакет с «продуктами», показанными ниже), похоже, ведет себя «очень лениво», хотя мое сопоставление настроено просто как ленивое:
<bag name="Products" cascade ="all" table="OrderProduct" mutable="true" lazy="true">
Я могу добавить коллекцию, не загружая ее в память.Я думаю, что вызов 'Count' приведет к загрузке заказов, если я не настрою его как 'extra-lazy'.
Может кто-нибудь прокомментировать, правильно ли это?