Nilmag
Nilmag

Reputation: 573

The entity or complex type 'OdeToFood.Models.RestaurantListViewModel' cannot be constructed in a LINQ to Entities query

As a part of the OdeToFood training package provided by pluralsight.

The error message:

An exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: The entity or complex type 'OdeToFood.Models.RestaurantListViewModel' cannot be constructed in a LINQ to Entities query.

The error is coming from(_Restaurant.cshtml) :

@model IEnumerable<OdeToFood.Models.RestaurantListViewModel>

<div id="restaurantList">
    @foreach (var item in Model)
    {
        <div>
            <h4>@item.Name</h4>
            <div>
            @item.City, @item.Country
            </div>
            <div> 
            Reviews: @item.CountOfReviews
            </div>
            <hr /> 
        </div>

    }
</div>

Index.cshtml

@model IEnumerable<OdeToFood.Models.RestaurantListViewModel>

    @{
        ViewBag.Title = "Home Page";
    }



<form method="get" action="@Url.Action("Index")"
    data-otf-ajax="true" data-otf-target="#restaurantList">

    <input type="search" name="searchTerm" />
    <input type="submit" value="Search By Name" />

</form>
@Html.Partial("_Restaurants", Model)

HomeController.cs

using OdeToFood.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Web;
using System.Web.Mvc;

namespace OdeToFood.Controllers
{
    public class HomeController : Controller
    {
        OdeToFoodDb _db = new OdeToFoodDb();

        public ActionResult Index(string searchTerm = null)
        {


            var model =
                _db.Restaurants
                .OrderByDescending(r => r.Reviews.Average(review => review.Rating))
                .Where(r => searchTerm == null || r.Name.StartsWith(searchTerm))
                .Take(10)
                .Select(r => new RestaurantListViewModel
                {
                    Id = r.Id,
                    Name = r.Name,
                    City = r.City,
                    Country = r.Country,
                    CountOfReviews = r.Reviews.Count()
                });

            if (Request.IsAjaxRequest())
            {
                return PartialView("_Restaurants", model);
            }

            return View(model);
        }

        public ActionResult About()
        {
            var model = new AboutModel();
            model.Name = "Tom";
            model.Location = "NYC, USA";

            return View(model);
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        protected override void Dispose(bool disposing)
        {
            if (_db != null)
            {
                _db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Is there something i am missing here? this problem wasn't well documented for a beginner so i created a question. I do apologise if it's a stupid mistake.

Upvotes: 2

Views: 580

Answers (1)

Rick Su
Rick Su

Reputation: 16440

It's because database has no knowledge about your RestaurantListViewModel, EntityFramework couldn't contruct underlying SQL query for that.

So, make extra call of .ToList() should solve the problem.

        var model =
            _db.Restaurants
            .OrderByDescending(r => r.Reviews.Average(review => review.Rating))
            .Where(r => searchTerm == null || r.Name.StartsWith(searchTerm))
            .Take(10)

            // The key is here
            .ToList()

            .Select(r => new RestaurantListViewModel
            {
                Id = r.Id,
                Name = r.Name,
                City = r.City,
                Country = r.Country,
                CountOfReviews = r.Reviews.Count()
            });

Upvotes: 5

Related Questions