2017-01-09 299 views
0

我正在访问类别的ICollection<Product> Products属性中的数据。如果您在下面查看我的控制器代码,使用第二个选择,我将每个产品的Form从产品实体更改为ProductViewModel,返回IQueryable<IEnumerable<ProductViewModel>>如何将List <IEnumerable <ProductViewModel >>转换为<IEnumerable <ProductViewModel >>?

最后,用ToListAsync()方法,模型返回List<IEnumerable<ProductViewModel>>,这是我的View不接受的。

我的控制器模型是这样的:

var model = (await db.Categories.Where(c => c.Id == id).Select(p => p.Products.Select(x => new 
        ProductViewModel { Id = x.Id, Name = x.Name, ByteImage = x.Image, Price = x.Price})).ToListAsync()); 

      return View(model); 

该模型的返回类型为List<IEnumerable<ProductViewModel>>,我无法通过这个模型我查看里面迭代中显示的数据。给予View

视图模型是:

@model IEnumerable<ProductViewModel>

这是错误消息我得到:

编译器错误消息:CS0411:用于方法“DisplayNameExtensions.DisplayNameFor(的HtmlHelper,表达式>)”的类型参数不能从使用推断。尝试明确指定类型参数。

Source Error: 

Line 14:  <tr> 
Line 15:   <th> 
Line 16:    @Html.DisplayNameFor(model => model.Name) 
Line 17:    
Line 18:   </th> 

ProductViewModel:

public class ProductViewModel 
    { 
     public int Id { get; set; } 
     [Required, Display(Name="Product Name")] 
     public string Name { get; set; } 
     [Required, DataType(DataType.Upload)] 
     public HttpPostedFileBase Image { get; set; } 
     public string OutputImage { get; set; } 
     public Byte[] ByteImage { get; set; } 
     [Required] 
     public Decimal Price { get; set; } 

     public static byte[] ConvertToByte(ProductViewModel model) 
     { 
      if (model.Image != null) 
      { 
       byte[] imageByte = null; 
       BinaryReader rdr = new BinaryReader(model.Image.InputStream); 
       imageByte = rdr.ReadBytes((int)model.Image.ContentLength); 

       return imageByte; 
      } 

      return null; 
     } 

     // ViewModel => Model | Implicit type Operator 
     public static implicit operator Product(ProductViewModel viewModel) 
     { 
      var model = new Product 
      { 
       Id = viewModel.Id, 
       Name = viewModel.Name, 
       Image = ConvertToByte(viewModel), 
       Price = viewModel.Price 
      }; 

      return model; 
     } 

     // Model => ViewModel | Implicit type Operator 
     public static implicit operator ProductViewModel(Product model) 
     { 
      var viewModel = new ProductViewModel 
      { 
       Id = model.Id, 
       Name = model.Name, 
       OutputImage = string.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(model.Image)), 
       Price = model.Price 
      }; 

      return viewModel; 
     } 

    } 

这是视图索引:

@model List<ValueVille.Models.ProductViewModel> 
@using MvcApplication8.Models 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table class="table"> 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => model.Name) 

     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Image) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Price) 
     </th> 
     <th></th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.Name) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Image) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Price) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | 
      @Html.ActionLink("Details", "Details", new { id=item.Id }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.Id }) 
     </td> 
    </tr> 
} 

</table> 
+3

看起来你只是想用'model.SelectMany(X => X)'变平的结果。 – juharr

+2

我真的没有吸收你的问题的肉。但是一个快速的解决方法是将你的LINQ中的第一个'.Select()'改成'.SelectMany()'。 –

+0

谢谢你。 – naz786

回答

7

您需要使用SelectMany代替:

(await db.Categories 
     .Where(c => c.Id == id) 
     .SelectMany(p => p.Products.Select(x => new ProductViewModel { Id = x.Id, Name = x.Name, ByteImage = x.Image, Price = x.Price })) 
     .ToListAsync()); 

SelectMany当您想从多个序列投影到单个(平面)序列时非常有用。


根据您的更新:

由于您的模型实际上是List<ProductViewModel>,当你想显示某些属性的名称时,需要内该列表指向一个实际ProductViewModel实例

例如:

@Html.DisplayNameFor(model => model[0].Name) 

MSDN

+0

谢谢你。我现在得到了从控制器返回的List ,并且View似乎有'@ Html.DisplayNameFor()'和'Html.DisplayFor()'标签助手发生红色下划线错误。有没有列出我需要使用的特定标签助手? – naz786

+1

@ Naz786,显示您的'ProductViewModel' – haim770

+0

我刚才将它包含在上面。 – naz786

1

此刻,你的序列是这样的

[ [model1, model2, model3], [model4, model] ] 

压扁它你可以

model.SelectMany(m => m) 

[ model1, model2, model3, model4, model5 ] 

(如果这是你真正想要什么)

+0

我正在使用请求'product/index/[Category ID]'访问数据,并且该类别特定的所有产品对象都应与查询一起显示。 – naz786

相关问题