2017-01-09 247 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

相關問題