Prashant G
Prashant G

Reputation: 4910

IQueryable to IEnumerable in ASP.NET MVC 5

Here's my code :

CONTROLLER:

    public async Task<ActionResult> Index()
    {
        if(User.IsInRole("admin")){
            return View(await db.Customers.ToListAsync());
        }
        else if(User.IsInRole("employee"))
        {
            var list = from c in db.Customers
                       where c.User.Id == User.Identity.GetUserId()
                       select c;
            var e = list.AsEnumerable();                
            return View(e);


            //tried this too : 
            //var list = db.Customers.Where(c=>c.User == User); 
            //return View(list);

        }
        return RedirectToAction("Error");
    }

VIEW :

@model IEnumerable<AspnetIdentitySample.Models.ApplicationUser>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.UserName)
        </th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.UserName)

            </td>

        </tr>
    }

</table>

Why can't I display the Query results to the view ? Any help would be appreciated! :) Thank you.

Upvotes: 0

Views: 3831

Answers (1)

Simon Whitehead
Simon Whitehead

Reputation: 65087

This is due to something called deferred execution. You're returning an IQueryable instance.. but this instance doesn't hold the data you want. It contains an execution plan with which to query for your results.

You need to force evaluation of the query. The general way of doing this is calling ToList() (Notice that you've done this on your other logical branch for the if statement):

return View(list.ToList());

Your problem (and the reason it all compiles) is because IQueryable implements IEnumerable. So passing it to your view is fine. IList also implements IEnumerable.. so ToList() forces evaluation of your IQueryable and can still be passed to the view.

There is also this issue in the view (outside of the foreach loop):

@Html.DisplayNameFor(model => model.UserName)

Your model is a collection.. so this won't work, since IEnumerable<T> doesn't have a UserName property (but its items do).

Upvotes: 4

Related Questions