0

I am trying to implement the server side processing for the data tables plugin in C# ASP.NET MVC controller.

This is my code:

public async Task<ActionResult> AjaxHandler(jQueryDataTableParamModel param)
{
    IEnumerable<Device> filteredItems;
    if (!string.IsNullOrEmpty(param.sSearch))
    {
        filteredItems = _db.Devices
                           .Where(c => c.AccountCode.Contains(param.sSearch) ||
                                       c.Company.ClientId.Contains(param.sSearch) ||
                                       c.FirmVersion.Contains(param.sSearch));
    }
    else
    {
        filteredItems = _db.Devices.Include(x => x.User);
    }

    var displayedItems = filteredItems.Skip(param.iDisplayStart).Take(param.iDisplayLength);
    var result = from c in displayedItems
                 select new[] { 
                     c.AccountCode, 
                     c.SerialNo ?? "None", 
                     "Company Name", 
                     c.User.FirstName};

    return Json(new { sEcho = param.sEcho,
                      iTotalRecords = _db.Devices.Count(),
                      iTotalDisplayRecords = filteredItems.Count(),
                      aaData = result }, 
                JsonRequestBehavior.AllowGet);

}

I am getting an error on the line where I select from displayedItems. I have debugged and found that the issue is specifically with c.User.Firstname

I have a feeling this is due to a lazy loading issue or something to do with the EF evaluates.

So my Question is why is EF giving me a null reference exception when I try and access the virtual Object User I have even explicitly included it?

I am using EF 6.1

And yes I know the async is invalid here. I was hoping to do async database calls here. So if someone can point out to me where to add those I would also appreciate it.

İsmet Alkan
  • 5,141
  • 3
  • 38
  • 64
Zapnologica
  • 20,003
  • 39
  • 136
  • 229
  • 2
    @Albireo I don't believe that is a duplicate of my question. My issue is relating specifically to linq and EF. – Zapnologica Oct 09 '14 at 13:50
  • 1
    You should start by breaking your linq query into multiple lines and multiple variables, so you can see exactly which part of the linq is failing. This is a basic NullReferenceException debug until you can prove otherwise. So @Albireo is correct to suggest the possible duplication. – Pete Garafano Oct 09 '14 at 13:51
  • @PeteGarafano I have stated in the Question which line it is. `c.User.Firstname` – Zapnologica Oct 09 '14 at 13:52
  • 1
    var displayedItems = filteredItems.Skip(param.iDisplayStart).Take(param.iDisplayLength).toList(); should evaluate and then c.User.Firstname would be available. – Anil Oct 09 '14 at 13:52
  • Then I don't really understand what your question is about. What are you asking for here? – Albireo Oct 09 '14 at 13:53
  • You're using EF, have you verified the input data is valid? You are 100% positive that, before the data goes into EF, `c.User.Firstname` is not null? – Pete Garafano Oct 09 '14 at 13:55
  • 2
    Could it be because you don't do `Include(x=>x.User)` in the `if` statement, only in the `else`? – juharr Oct 09 '14 at 13:56
  • @PeteGarafano Even if username its self was null It should not throw exception as I am not calling `.toString()` or anything on it. But yes as a matter of fact. It does have a value. I do believe this is due to lazy loading. – Zapnologica Oct 09 '14 at 13:57
  • @juharr Well Spotted. Unfortunately I am not hitting the if statement in my debug. So that isnt the issue, But I will look into that for when I start searching. – Zapnologica Oct 09 '14 at 13:58
  • 2
    `filteredItems` should be an `IQueryable`, not an `IEnumerable`. You're doing almost all of your query in linq to objects, not using EF, when you should be doing pretty much all of this work on the DB side of things. – Servy Oct 09 '14 at 13:59
  • Just try @akfkmupiwu suggestion, call `ToList()` on `displayedItems`, it might help `var displayedItems = filteredItems.Skip(param.iDisplayStart).Take(param.iDisplayLength).ToList();`. – Michael Oct 09 '14 at 14:00
  • @Servy That makes sense, I have changed it and I am now getting: `The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.` – Zapnologica Oct 09 '14 at 14:10
  • @Zapnologica I would think that the error message is pretty self explanatory as to what's wrong and what you need to do to fix it. – Servy Oct 09 '14 at 14:12
  • @michaelmoore I agree, however do I not want EF to do my quesry? If i call .tolist() before I do the take. it will pull the whole list from the db? – Zapnologica Oct 09 '14 at 14:12
  • 1
    @michaelmoore No, actually, in fact it's important that those operation *not* be executed on the client side here. The fact that they are is exactly why it's failing with a NRE, not that the operation makes sense to do on the client side in the first place. – Servy Oct 09 '14 at 14:12
  • 1
    @Zapnologica yes what Servy is saying is right, you should let EF to do operations for you. – Michael Oct 09 '14 at 14:15
  • @Servy I agree with you, I missed the part that filteredItems were declared as `IEnumerable`. – Michael Oct 09 '14 at 14:16

0 Answers0