C#在linq查询中转换列表抛出异常

时间:2016-10-13 10:21:06

标签: c# asp.net-mvc entity-framework linq

我有关于列表列表问题的问题。

我的模特:

public partial class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public string SparePartName { get; set; }
    public Nullable<decimal> SparePartPrice { get; set; }
    public Nullable<decimal> Labor { get; set; }
    public Nullable<decimal> Total { get; set; }
    public string Comment { get; set; }
}

public partial class Orders
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public int StorageId { get; set; }
    public int UserId { get; set; }
    public Nullable<System.DateTime> DateEntry { get; set; }
    public Nullable<System.DateTime> DateRelease { get; set; }
    public Nullable<System.DateTime> DateEstimatedRelease { get; set; }
    public Nullable<System.DateTime> DateUpdate { get; set; }
    public Nullable<decimal> Price { get; set; }
    public int Status { get; set; }
    public string FollowCode { get; set; }
    public string DeviceBrand { get; set; }
    public string DeviceModel { get; set; }
    public string DeviceSerialNumber { get; set; }
    public string DeviceComplaint { get; set; }
    public string Comment { get; set; }
}

我的ViewModel:

public class VMOrderEdit
{
    public int Id { get; set; }
    public int StorageId { get; set; }
    public int UserId { get; set; }
    public string StorageName { get; set; }
    public string CustomerName { get; set; }
    public string CustomerTelephone { get; set; }
    public DateTime? DateEntry { get; set; }
    public DateTime? DateUpdate { get; set; }
    public DateTime? DateRelease { get; set; }
    public DateTime? DateEstimatedRelease { get; set; }
    public decimal? Price { get; set; }
    public string StatusName { get; set; }
    public string FollowCode { get; set; }
    public string DeviceBrand { get; set; }
    public string DeviceModel { get; set; }
    public string DeviceSerialNumber { get; set; }
    public string DeviceComplaint { get; set; }
    public string Comment { get; set; }
    public int MyProperty { get; set; }
    public List<VMOrderEditDetails> Details { get; set; }
}
public class VMOrderEditDetails
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public string SparePartName { get; set; }
    public decimal SparePartPrice { get; set; }
    public decimal Labor { get; set; }
    public decimal Total { get; set; }
    public string Comment { get; set; }
}

我的控制器:

List<VMOrderEdit> OrderEditObj = (from o in DB.Orders
                                  join sn in DB.OrderStatusName on o.Status equals sn.Id
                                  join st in DB.Storages on o.StorageId equals st.Id
                                  join c in DB.Customers on o.CustomerId equals c.Id
                                  where o.Id == Id
                                  select new VMOrderEdit()
                                  {
                                      Id = o.Id,
                                      StorageId = o.StorageId,
                                      StorageName = st.Name,
                                      UserId = o.UserId,
                                      CustomerName = c.NameSurname,
                                      CustomerTelephone = c.Telephone,
                                      DateEntry = o.DateEntry,
                                      DateUpdate = o.DateUpdate,
                                      DateRelease = o.DateRelease,
                                      Price = o.Price,
                                      StatusName = sn.Name,
                                      FollowCode = o.FollowCode,
                                      DeviceBrand = o.DeviceBrand,
                                      DeviceModel = o.DeviceModel,
                                      DeviceSerialNumber = o.DeviceSerialNumber,
                                      DeviceComplaint = o.DeviceComplaint,
                                      Comment = o.Comment,
                                      Details = DB.OrderDetail.Where(x => x.OrderId == o.Id).ToList()
                                      }
                               ).ToList();

在这一行:

Details = DB.OrderDetail.Where(x => x.OrderId == o.Id).ToList()

visual studio给出了这个错误:

  

无法隐式转换类型   'System.Collections.Generic.List'到   “System.Collections.Generic.List

我该如何处理这个错误?

5 个答案:

答案 0 :(得分:2)

数据库返回OrderDetails的对象,但Details列表属性中的项目属于VMOrderEditDetails类型。

在分配之前,您必须将每个项目从OrderDetails转换为VMOrderEditDetails

  1. 您可以在Select之后添加。.Where,以便在行中.ToList()之前转换为该类型,但异常(请参阅代码选项2)

    Details = DB.OrderDetail.Where(x => x.OrderId == o.Id)
                            .Select(x => new VMOrderEditDetails { /* your conversion*/})
                            .ToList()
    
  2. 更好的解决方案是在此之前添加额外的GroupJoin,然后在.Select中进行转换,而不是检索数据:

    List<VMOrderEdit> OrderEditObj = (from o in DB.Orders
                                      join sn in DB.OrderStatusName on o.Status equals sn.Id
                                      join st in DB.Storages on o.StorageId equals st.Id
                                      join c in DB.Customers on o.CustomerId equals c.Id
                                      join d in DB.OrderDetails on o.Id equals d.OrderId into d 
                                      where o.Id == Id
                                      select new VMOrderEdit()
                                      {
                                          Id = o.Id,
                                          StorageId = o.StorageId,
                                          //All the other properties
                                          Comment = o.Comment,
                                          Details = d.Select(x => new VMOrderEditDetails{ /*your convertion*/ }).ToList()
                                      }).ToList();
    
  3. 因为您正在使用实体框架,所以更好的选择是 使用导航属性替换所有join,然后仍然在底部进行转换。

答案 1 :(得分:2)

您尝试将OrderDetail的列表分配给VMOrderEditDetails,但必然会失败。

您的LINQ查询应该如下所示。我还没有对Select进行可空的检查和转换。它可以由你完成,非常简单。如果有帮助,请标记为答案。

 Details = DB.OrderDetail.Where(x => x.OrderId == o.Id).Select(x=>new VMOrderEditDetails{
    Id = x.Id,
    OrderId = x.OrderId,
    SparePartName = x.SparePartName,
    SparePartPrice = x.SparePartPrice,
    Labor = x.Labor,
    Total = x.Total,
    Comment = x.Comment
}).ToList()

答案 2 :(得分:1)

DB.OrderDetail
  .Where(x => x.OrderId == o.Id)
  .ToList()

应该是

DB.OrderDetail
  .Where(x => x.OrderId == o.Id)
  .Select(x => new VMOrderEditDetails () 
  { 
      Id = x.OrderId
  })
  .ToList<VMOrderEditDetails>()

因为types不同

答案 3 :(得分:1)

试试这个,

Details = DB.OrderDetail.Where(x => x.OrderId == o.Id)
            .Select(x => new VMOrderEditDetails {
                       Id = x.Id,
                       OrderId = x.OrderId,
                       SparePartName = x.SparePartName,
                       SparePartPrice = x.SparePartPrice.Value,
                       Labor = x.Labor.Value,
                       Total = x.Total.Value,
                       Comment = x.Comment
                   }).ToList()

答案 4 :(得分:0)

DetailsList<VMOrderEditDetails>类型,但您尝试为其分配List<OrderDetail>值,请将其设为这样

Details = DB.VMOrderEditDetails.Where(x => x.OrderId == o.Id).ToList()