Entity Framework лениво загружает связанные объекты, когда к свойствам навигации нет доступа

Я пытаюсь отладить проблемы с производительностью в более старом приложении MVC, используя EF 5 (4.4). SQL Server Profiler показывает, как выполняется больше запросов, чем должно быть. Похоже, что EF генерирует запросы для каждой связанной сущности с рассматриваемой моделью.

Теперь это звучит как ленивая загрузка. Дело в том, что никакие свойства навигации нигде в коде не упоминались (по крайней мере, явно).

Когда я отключаю ленивую загрузку для контекста, он исправляет это. Кроме того, если я возвращаю что-то отличное от модели (например, модель представления), это исправляет это. Это старое, плохо реализованное приложение MVC, и в любом случае оно должно использовать модели представления, так что все в порядке. Любое из этих исправлений приемлемо, но я все равно хочу знать, почему это происходит.


Я читал, что свойства навигации могут вызываться при сериализации объекта. Это то, что здесь происходит? Если да, можете ли вы объяснить, почему объект сериализуется? (Отметим, что мое понимание сериализации очень простое - в основном то, что сказано здесь.)


Вот пример:

Контроллер

    [HttpGet]
    public ViewResult StoreInfo(int id)
    {
        Store model = _posRepository.GetStore(id);

        return View(model);
    }

Репозиторий

    public Store GetStore(int storeID)
    {
        return _dbContext.Store.Single(x => x.StoreID == storeID);
    }

Модель

public partial class Store // highly simplified version
{           
    public int StoreID { get; set; }        
    public string StoreName { get; set; }        
    public Nullable<int> StateID { get; set; }          

    public virtual States State { get; set; } // lazy loaded
}

Просмотреть

// blank

person EF0    schedule 19.02.2015    source источник
comment
Здесь нет никакой сериализации. Когда вы передаете модель для просмотра, она передает ее как объект. Он не выполняет никакой сериализации. Он будет сериализовать его только в том случае, если вы используете Json(model), поэтому проблема в другом.   -  person Sergey Litvinov    schedule 19.02.2015
comment
Спасибо за информацию - я не был уверен, что фреймворк делает это за кулисами или что-то в этом роде.   -  person EF0    schedule 19.02.2015
comment
Так же, как и другой образец — dotnetfiddle.net/T9fYud. Здесь я использовал ту же модель, но без EF. Он использует MVC4 внутри. Он имеет Console.WriteLine вызовов в методе доступа к свойствам. Он пишет в конец dotnetfiddle, и, как вы видите, доступ к свойству State во время рендеринга представления не производился.   -  person Sergey Litvinov    schedule 19.02.2015


Ответы (2)


Я обнаружил, что Glimpse (действительно полезный диагностический инструмент для ASP.NET) обращается к свойствам навигации на вкладке "Метаданные" ( см. мой другой вопрос, который оказался связаны). Только после того, как я отключил отложенную загрузку и изучил стек вызовов, я не получил NullReferenceException для свойства nav, когда я отключил ленивую загрузку, и понял, что он исходит от Glimpse. Поскольку модель EF передавалась непосредственно в представление, а не в модель представления, при заполнении метаданных она обращалась к свойствам навигации, вызывая запросы к базе данных. Когда я отключил вкладку метаданных Glimpse, это решило проблему.

person EF0    schedule 20.02.2015

Без использования третьих лиц вы можете добиться этого с помощью анонимного объекта.

var dataList= _dbContext.Store.Single(x => x.StoreID == storeID); var jsonData= dataList.Select(c=> new {c.StoreID, c.StoreName, c.StateID, StateName=c.State?.Name, StateCode=c.State?.Code});

вернуть Json(jsonData, JsonRequestBehavior.AllowGet);

Надеюсь, теперь все в порядке

person Sraban75    schedule 14.12.2019