Search code examples
c#asp.net-mvcrazor

Why use @model IQueryable<> in the Razor View


Is using @model IQueryable<> in a Razor view a good idea? Any suitable scenario in which you would use @model IQueryable<> in the Razor view?

I just replaced IQueryable<> with List<> in some legacy code. There is no elder developer in the company to ask of.

@model IQueryable<T>
@{
    ViewBag.Title = "Index";
}

<table class="table">
    <tr>
        <th></th>
        <th>Sn</th>
        <th>Kind</th>
    </tr>
    @{
        var count = 1;
    }
    @using (Entities db = new Entities())
    {
        foreach (var item in Model)
        {
            <tr>
                <td>
                    <button type="button" class="btn_delKind btn btn-danger" data-kind-id="@item.id">Delete</button>
                </td>
                <td>@count</td>
                <td>
                    @switch (item.Type)
                    {
                        case 0:
                            @Html.Raw("All")
                            break;
                        default:
                            @Html.Raw(db.LookupType.Find(item.Type).Name)
                            break;
                    }
                </td>
            </tr>
            count = count + 1;
        }
    }
</table>

Before edit - my previous point of views:

  1. Costs larger memory (Resource concern)
  2. The way to manipulate model will rely on server side, hard to transfer to frontend javascript (separation of concern)
  3. Very likely generates more C# LINQ codes surrounding by HTML. Not a simple, static, well-structured object to use for rendering. (Performance concern)

After collect comments and answers (thanks for those)

  1. unexpected memory usage
  2. unexpected query counts
  3. violation of the MVC pattern

Solution

  • To answer your question - no, there is no reason for using IQueryable<T> in view.

    Whole purpose of IQueryable<T> is to provide mechanism, that allows you to write C# code, which can be translated to some other form understandable by other programs/tools. In this case, assuming you're using Entity Framework, IQueryable<T> interface defines methods, that allows Entity Framework to transform your query from C# to SQL. This can be done using expression trees. Using expression trees is the main difference between IEnumerable<T> and IQueryable<T>.

    It's not true, that IQueryable uses more memory than IEnumerable. With IEnumerable you keep your objects in memory, so you have to allocate space for every object in your collection. IQueryable defines interface for querying data, so you don't need to store anything in memory.

    In your view you need to be able to iterate through your collections and display specific set of data. To do that methods provided by IEnumerable are more than enough. Using IQueryable in your view won't do anything good for you, but might cause a lot of problems, as was already mentioned in comments.