当我将 select 子句更改为 select new Model 时,为什么此 linq 查询失败
Why does this linq query fail when I change the select clause to select new Model
为什么这个查询有效:
var rooms = from m in db.Rooms
where
m.FK_HotelID == id
select m;
return View(rooms.ToList());
但是这个查询(我从一个名为 'Linqer' 的程序生成的)似乎失败了?
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());
我需要帮助来查询 return 个 List
个 Room
个对象。
我不认为我可以使用匿名类型或 DTO 模型进行查询,因为视图需要 Room
类型的对象。查询确实 return 在 Linqer 程序中产生结果,但是当我尝试在我的 VS2013 项目中获取此视图时,我收到以下错误消息:
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.
P.S,这是我的房间class供参考:
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; }
}
因为您在这里使用 LINQ To SQL
,这意味着该查询被翻译成 SQL
,它不知道您的自定义类型。
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());
这里发生的是:
1) 第一个查询转到 SQL 并找到您需要的所有房间。
2)然后翻译成C#对象的List。
3) 此时的第二个查询正在使用 LINQ To Objects
,因此可以使用您的自定义模型。
更好的解决方案是创建一个 ViewModel
,其中包含您需要的所有字段,例如:
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
}
然后将您的 DTO
映射到这个新的 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());
那是因为 Room
是您的映射实体之一,并且不允许投影到映射实体。您将不得不使用 DTO 或项目到匿名类型。
为什么这个查询有效:
var rooms = from m in db.Rooms
where
m.FK_HotelID == id
select m;
return View(rooms.ToList());
但是这个查询(我从一个名为 'Linqer' 的程序生成的)似乎失败了?
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());
我需要帮助来查询 return 个 List
个 Room
个对象。
我不认为我可以使用匿名类型或 DTO 模型进行查询,因为视图需要 Room
类型的对象。查询确实 return 在 Linqer 程序中产生结果,但是当我尝试在我的 VS2013 项目中获取此视图时,我收到以下错误消息:
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.
P.S,这是我的房间class供参考:
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; }
}
因为您在这里使用 LINQ To SQL
,这意味着该查询被翻译成 SQL
,它不知道您的自定义类型。
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());
这里发生的是:
1) 第一个查询转到 SQL 并找到您需要的所有房间。
2)然后翻译成C#对象的List。
3) 此时的第二个查询正在使用 LINQ To Objects
,因此可以使用您的自定义模型。
更好的解决方案是创建一个 ViewModel
,其中包含您需要的所有字段,例如:
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
}
然后将您的 DTO
映射到这个新的 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());
那是因为 Room
是您的映射实体之一,并且不允许投影到映射实体。您将不得不使用 DTO 或项目到匿名类型。