1
votes

I am getting this error in @foreach(var item in Model) line.

How can I fix it?

LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[System.Char] ToList[Char](System.Collections.Generic.IEnumerable1[System.Char])' method, and this method cannot be translated into a store expression.

Controller

 public ActionResult ProductIndex(int pageno= 0)
 {
     ViewBag.PageNumber= Paging.CountPageNumber(db.Products.Count(), 8);
     ViewBag.ActivePageNo= sayfaNo;
     var product = db.Products.OrderBy(x => 
         x.Name.Skip(pageno* 8).Take(8).ToList());
     return View(product);
 }

View

<tr>
    <th>ID</th>
    <th>Name</th>
    <th>Price</th>
    <th>Brand</th>
    <th>Category</th>
    <th>Size</th>
    <th>Stock</th>
    <th>Active</th>
    <th>Edit</th>
</tr>
@foreach (var item in Model)
{
    <tr>
        <td>@item.Id</td>
        <td class="box-title" data-original-title="click to edit">
            @Html.ActionLink(item.Name, "ProductDetails", new { id = item.Id })
        </td>
        <td>@item.Price</td>
        <td>@item.Brand</td>
        <td>@item.Category.Name</td>
        <td>@item.Size</td>
        <td>@item.StockQuantity</td>
        @if (item.IsActive)
        {
            <td>Aktif</td>
        }
        else
        {
            <td>Pasif</td>
        }
        <td>
            <a href="../Admin/SupplierEdit/@item.Id">
                <i class="fa fa-pencil-square-o"></i>Edit
            </a>&nbsp;&nbsp;
            @if (item.IsActive)
            {
                 <a href="../Admin/ProductDelete/@item.Id">
                    <i class="fa fa-minus-circle"></i>Delete
                 </a>
            }
            else
            {
                <a href="../Admin/ProductDelete/@item.Id">
                    <i class="fa fa-check"></i>Activate
                </a>
            }
        </td>
    </tr>
}
2

2 Answers

7
votes

you have a parenthesis in the wrong spot in your LINQ:

db.Products.OrderBy(x => x.Name.Skip(pageno* 8).Take(8).ToList());

You want:

db.Products.OrderBy(x => x.Name).Skip(pageno* 8).Take(8).ToList();

As it is, it's not actually performing the query until the view (and then erroring), because you aren't calling ToList on the outer query. EF only retrieves the data when it is needed.

The latter query is very common for pagination. The former doesn't really make sense.

0
votes

LINQ to Entities is building an expression tree and translating that into code to execute against the data store, likely a SQL database. There's no concept of .ToList() in SQL.

In this line:

db.Products.OrderBy(x => x.Name.Skip(pageno* 8).Take(8).ToList())

Everything inside of the OrderBy is going to be executed on the SQL server. So you don't need the .ToList():

db.Products.OrderBy(x => x.Name.Skip(pageno* 8).Take(8))

There are SQL analogues for OrderBy, for Skip, for Take, and the literal values are passed as parameters to the resulting SQL query. But not ToList.

You can use .ToList() on the result of the query, if you want to materialize it immediately:

db.Products.OrderBy(x => x.Name.Skip(pageno* 8).Take(8)).ToList()

This is because the result is basically the enumerable representing the expression tree that's ready to be sent to the data store. It doesn't actually execute against the data store until something materializes it.

If you don't do this then what you pass to the view will be an enumerable that's ready to be evaluated (materialized). If there are any errors evaluating it, those errors will make themselves known in the view's server-side code. If you explicitly call .ToList() then any errors in evaluating the LINQ query against the data store will make themselves known in the controller.