简体   繁体   中英

Why does this linq query fail when I change the select clause to select new Model

Why does this query work:

var rooms = from m in db.Rooms
                      where
                      m.FK_HotelID == id
                      select m;

            return View(rooms.ToList());

but this query (which I generated from a program called 'Linqer') seemingly fails?

var rooms = from m in db.Rooms
                      where
                      m.FK_HotelID == id
                      select new Room
                      {
                          RoomID = m.RoomID,
                          RoomNumber = m.RoomNumber,
                          RoomType = m.RoomType,
                          FK_HotelID = m.FK_HotelID
                      };

            return View(rooms.ToList());

I need help in getting the query to return a List of Room objects. I don't think I can use an anonymous type or a DTO Model for the query because the View requires objects of the type Room . The query does return results in the Linqer program but when I try to get this view in my VS2013 Project, I get the following 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 'HotelApp.Models.Room' cannot be constructed in a LINQ to Entities query.

PS, Here is my Room class for reference:

public partial class Room
{
    public Room()
    {
        Bookings = new HashSet<Booking>();
    }
    public int RoomID { get; set; }
    public int RoomNumber { get; set; }
    public string RoomType { get; set; }
    public int? FK_HotelID { get; set; }
    public virtual ICollection<Booking> Bookings { get; set; }
    public virtual Hotel Hotel { get; set; }
}

Because you are using LINQ To SQL here which means, that query is translated to SQL that has no idea about your custom types.

    var rooms = (from m in db.Rooms
                      where
                      m.FK_HotelID == id
                      select m).ToList();

    var roomsVm = from m in rooms select new Room
                      {
                          RoomID = m.RoomID,
                          RoomNumber = m.RoomNumber,
                          RoomType = m.RoomType,
                          FK_HotelID = m.FK_HotelID
                      };

            return View(roomsVm.ToList());

What happens here is:

1) The first query goes to SQL and finds all the rooms you need.

2) Then it is translated to the List of C# objects.

3) The second query at this point is using LINQ To Objects and therefore can use your custom model.


Better solution for you would be to create a ViewModel that would contain all the fields you need sth like:

public class RoomViewModel {
    public int RoomId {get;set;}
    public string RoomNumber {get;set;}
    public string HotelName {get;set;}
//and all other properties you need on your View
}

then map your DTO to this new ViewModel :

var roomsVm = from m in rooms select new RoomViewModel
                          {
                              RoomId = m.RoomID,
                              RoomNumber = m.RoomNumber,
                              HotelName = m.Hotel.HotelName
                              //and other properties
                          };

                return View(roomsVm.ToList());

That's cause Room is one of your mapped entity and projecting to a mapped entity is not allowed. You will have to use a DTO or project to an anonymous type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM