[英]How to convert List<IEnumerable<ProductViewModel>> into <IEnumerable<ProductViewModel>>?
I am accessing data from a Category's ICollection<Product> Products
property. 我正在从类别的
ICollection<Product> Products
属性访问数据。 If you look at my controller code below, using the second select, I change each product's Form
from a Product entity into a ProductViewModel which returns an IQueryable<IEnumerable<ProductViewModel>>
. 如果您在下面查看我的控制器代码,则使用第二个选择,将每个产品的
Form
从Product实体更改为ProductViewModel,该产品返回IQueryable<IEnumerable<ProductViewModel>>
。
Finally, with the ToListAsync()
method, the model returns a List<IEnumerable<ProductViewModel>>
which is not accepted by my View
. 最后,使用
ToListAsync()
方法,模型返回一个List<IEnumerable<ProductViewModel>>
,该View
未被View
接受。
My controllers model is this: 我的控制器模型是这样的:
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);
The return type for this model is List<IEnumerable<ProductViewModel>>
and I cannot iterate through this model inside my View to display the data. 该模型的返回类型为
List<IEnumerable<ProductViewModel>>
并且我无法在视图内迭代该模型以显示数据。
View model given to the View
is: 给视图模型
View
是:
@model IEnumerable<ProductViewModel>
. @model IEnumerable<ProductViewModel>
。
This is the error message I get: 这是我收到的错误消息:
Compiler Error Message: CS0411: The type arguments for method 'DisplayNameExtensions.DisplayNameFor(HtmlHelper, Expression>)' cannot be inferred from the usage.
编译器错误消息:CS0411:无法从用法中推断出方法'DisplayNameExtensions.DisplayNameFor(HtmlHelper,Expression>)'的类型参数。 Try specifying the type arguments explicitly.
尝试显式指定类型参数。
Source Error:
Line 14: <tr>
Line 15: <th>
Line 16: @Html.DisplayNameFor(model => model.Name)
Line 17:
Line 18: </th>
ProductViewModel: 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;
}
}
This is the View Index: 这是视图索引:
@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>
You need to use SelectMany
instead: 您需要使用
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
is useful when you want to project from multiple sequences into a single (flat) sequence. 当您要从多个序列投影到单个(平面)序列中时,
SelectMany
很有用。
As per your update: 根据您的更新:
Since your model is actually List<ProductViewModel>
, when you want to display the name of certain property, you need to point to an actual ProductViewModel
instance within that list. 由于您的模型实际上是
List<ProductViewModel>
当你想显示某些属性的名称,你需要指向一个实际ProductViewModel
该列表中的实例。
For example: 例如:
@Html.DisplayNameFor(model => model[0].Name)
At the moment, you sequence looks like this 此刻,您的序列看起来像这样
[ [model1, model2, model3], [model4, model] ]
to flatten it you could 把它弄平
model.SelectMany(m => m)
for 对于
[ model1, model2, model3, model4, model5 ]
(if that's really what you want) (如果这确实是您想要的)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.