0

I am trying to debug performance problems with an older MVC application, using EF 5 (4.4). SQL Server Profiler reveals way more queries are being ran than should be. EF appears to be generating queries for every related entity to the model in question.

Now this sounds like lazy-loading. The thing is, no navigation properties were referenced anywhere in code (at least not explicitly).

When I turn lazy loading off for the context, it fixes it. Also, if I return something other than the model (such as a viewmodel), it fixes it. This is an old, poorly implemented MVC app - and it should be using viewmodels anyway, so that's fine. Either of these are acceptable fixes, but I still want to know why it's happening.


I have read that navigation properties may get invoked when the object is serialized. Is that what's happening here? If so, can you explain why the object is being serialized? (Noting that my understanding of serialization is very basic - basically what is said here.)


Here's an example:

Controller

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

        return View(model);
    }

Repository

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

Model

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
}

View

// blank
Community
  • 1
  • 1
EF0
  • 2,940
  • 4
  • 17
  • 23
  • 1
    There is no serialization here. When you pass model to view it passes it as object. It doesn't do any serialization. It will serialize it only if you use `Json(model)`, so the problem is somewhere else – Sergey Litvinov Feb 19 '15 at 00:14
  • Thanks for the info - I wasn't sure if the framework was doing it behind the scenes or something. – EF0 Feb 19 '15 at 14:10
  • 1
    Just as another sample - https://dotnetfiddle.net/T9fYud . Here i used the same model but without EF. It uses MVC4 internally. It has `Console.WriteLine` calls in property accessor. It writes to the bottom of dotnetfiddle, and as you can see - `State` property wasn't accessed during view rendering – Sergey Litvinov Feb 19 '15 at 16:01

2 Answers2

0

I found out that Glimpse (a really useful diagnostic tool for ASP.NET) was accessing navigation properties for its Metadata tab (see my other question which turned out to be related). It wasn't until I had a NullReferenceException thrown on a nav property when I disabled lazy-loading, and examined the call stack that I figured out it was coming from Glimpse. Since the EF model was being passed directly to the view instead of a viewmodel, when it populated the Metadata, it was accessing the nav properties, causing database queries. When I disabled Glimpse's Metadata tab, it solved the problem.

Community
  • 1
  • 1
EF0
  • 2,940
  • 4
  • 17
  • 23
0

Without any Third party use, u can achieve this by anonymous Object.

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});

return Json(jsonData, JsonRequestBehavior.AllowGet);

Hope now Everything is Okay

Sraban75
  • 85
  • 9