2014-12-19 2 views
4

У меня есть приложение ASP.NET MVC, использующее Entity Framework для слоя данных.Отключение ленивой Загрузка опасно?

В одном из моих методов я получаю данные о сезонной доступности продукта, а затем - лучшую налоговую ставку для продукта.

public ProductList FetchProductSearchList(ProductSearchCriteria criteria) 
{ 
    ... 
    var avail = ProductAvailabilityTemplate.Get(criteria.ProductID); 
    ... 
    var tr = TaxRate.BestMatchFor(criteria.ProductID, criteria.TaxCode); 
    ... 
} 

В слое данных для ProductAvailabilityTemplate.Get, я был оптимизации производительности моего кода LINQ. В частности, я установил ctx.ObjectContext.ContextOptions.LazyLoadingEnabled = false;, чтобы предотвратить загрузку некоторых объектов (через свойства навигации), которые мне не нужны в этом сценарии.

Однако, как только это изменение было внесено, я заметил, что мои налоговые реестры не загружались полностью, потому что ctx.ObjectContext.ContextOptions.LazyLoadingEnabled все еще был ложным в моем коде слоя данных налогообложения. Это означало, что объект, связанный с TaxRate через свойство навигации, не загружается.

Чтобы преодолеть эту проблему, я просто установил ctx.ObjectContext.ContextOptions.LazyLoadingEnabled = true; в методе уровня налоговых данных, но я обеспокоен тем, что несвязанные изменения могут вызвать такую ​​проблему. Кажется, что вы не можете безопасно отключить ленивую загрузку для одной функции, не оказывая потенциального влияния на работу того, что вызывается впоследствии. У меня возникает соблазн удалить все свойства навигации, отключить ленивую загрузку и использовать старые старомодные соединения для загрузки именно того, что мне нужно для каждого вызова уровня данных, не более того.

Приветствуем любые советы.

+0

«В частности, я установил' ctx.ObjectContext.ContextOptions.LazyLoadingEnabled = false; ', чтобы предотвратить загрузку некоторыми объектами EF (через свойства навигации), которые мне не нужны в этом сценарии ». - Lazy loading заставляет объекты загружаться при доступе к свойствам навигации, поэтому, если они вам не нужны, почему вы получаете доступ к этим свойствам? Если они вам не нужны и просто не используют их, они не загрузятся. – hvd

ответ

2

Я любил ленивую загрузку, когда начал использовать EF, но через некоторое время я понял, что это влияет на производительность, поскольку оно эффективно отключает объединения и вытягивает все подтадаты в отдельных запросах, даже если вам нужно потреблять все сразу.

Так что теперь я, а с помощью Включает жадно загрузки суб-объекты, которые я заинтересован в Вы также можете сделать это несколько динамичны, например, путем предоставления includeDetails параметр:.

public IEnumerable<Customer> LoadCustomersStartingWithName(string name, bool includeDetails) 
{ 
    using (var db = new MyContext()) 
    { 
     var customers = db.Customers; 
     if (includeDetails) 
      customers = customers.Include(x => x.Orders).Include(x => x.ContactPersons); 

     customers = customers.Where(x => x.Name.StartsWith(name)); 

     return customers;   
    } 
} 

для кода для работы в EF6, вам также необходимо включить

using System.Data.Entity; 

в верхней части класса

2

It «Са Компромисс:

Ленивый Loading

  • дает преимущество не нуждаясь указать глубину графа во время загрузки
  • нужно будет вернуться в базу данных для получения недостающих результатов
  • требует некоторого загрязнения POCO (например, virtual свойства с проксими)
  • требует, чтобы DbContext был более долговечным, на протяжении всего доступа к данным.

Нетерпеливый Загрузка

  • требует гораздо больше мысли в глубину загрузки во время каждой выборки
  • обычно генерируют меньше запросов с более широким присоединяется извлечь график сразу
  • делает не требуют каких-либо изменений или церемоний вокруг ваших организаций
  • Позволяет использовать гораздо более короткие соединения и DbContexts

FWIW, я вообще сделал прототип работа с отложенной загрузкой включена, чтобы получить программное обеспечение в очевидное состояние, и после того, как модели доступа к данным стабилизации, а затем отключить отложенную загрузку и перейти к явно Include г ссылки. Несколько тестов на единицу измерения для нулевых ссылок также будут делать чудеса на этом этапе. Я не хочу поставлять производственную систему с включенной Lazy Загрузка, поскольку есть элемент недетерминированности (например, трудно полностью проверить), и необходимость возврата к БД для дальнейших данных может повредить производительность.

В любом случае, я бы не отключил всю навигацию и не делал явных совпадений - вы теряете силу навигации, которую обеспечивает ORM. Когда вы переключаетесь с Lazy Loading, просто явным образом определяйте объекты, которые должны быть загружены применимыми Includes

Смежные вопросы