如何通过 ID 访问 IEnumerable 模型的项目 2(或 3 或 ...x)
How to access item 2 (or 3 or ...x) of an IEnumerable Model by ID
我正在寻找最佳实践。我有一些有用的东西,但我不知道它是否“正确”。
我正在构建一个页面,客户可以在其中输入三种不同类型许可证的付款数据。我正在发送我的许可证的 IEnumerable。它包含 3 个空许可证。
澄清:最终用户可以拥有 1、2 或 3 个许可证,每个许可证的类型都是唯一的——“钓鱼”、“划船”或“特许权”。
我围绕这个概念构建了视图:
<div class="form-group row">
<div class="col-md-2" align="right" style="padding-top:5px">
<strong>@Html.LabelFor(model => model.FirstOrDefault().Notes, "Notes:", htmlAttributes: new { @class = "control-label" })</strong>
</div>
<div class="col-md-9">
<div class="row">
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Skip(1).Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Skip(1).Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Skip(2).Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Skip(2).Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
客户为每个适当的支付类型输入数据,保存按钮将数据发回,我检查每个支付类型是否不为空,然后照常处理。
这样做正确吗?有没有更好的方法?
如有任何意见,我们将不胜感激。
此致,
迦太基
您可以在标记中使用 foreach
循环来遍历可枚举对象。
<div class="form-group row">
<div class="col-md-2" align="right" style="padding-top:5px">
<strong>@Html.LabelFor(model => model.FirstOrDefault().Notes, "Notes:", htmlAttributes: new { @class = "control-label" })</strong>
</div>
<div class="col-md-9">
<div class="row">
foreach (var item in Model)
{
<div class="col-md-4" align="left">
@Html.EditorFor(modelItem => item.Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(modelItem => item.PermitTypeId, "", new { @class = "text-danger" })
</div>
}
</div>
</div>
</div>
无法通过索引直接访问IEnumerable。您可以使用的更具可读性的循环语句是 foreach,然后使用 if 语句检查 ID。
由于此搜索的最复杂度为 O(n),因为它必须针对每个项目进行循环,因此 forach 解决方案对我来说没问题。
我不完全了解您的代码库或模型,但如果您仅在其中一个 ID 为 null 时验证失败,那么以下代码将是我最好的收获:
private bool ValidateCollection(IEnumerable<Item> itemsCollction)
{
foreach(Item item in itemsCollction)
{
if(item.ID == null)
return false; // At least one of the elements have ID null.
}
return true;
}
只想说:
也可以使用 LINQ,但平均情况下执行速度远低于 foreach,因为 LINQ 查询会产生大量开销。
您可以使用构造函数将枚举对象转换为数组或列表,但它仍然必须循环遍历集合中的每个项目。然后你可以使用 for 循环执行比 foreach 更好的数组,但这只有在你经常重用第一次转换的结果时才有用。否则,您将浪费时间将 IEnumerable 转换为列表或数组。
我正在寻找最佳实践。我有一些有用的东西,但我不知道它是否“正确”。
我正在构建一个页面,客户可以在其中输入三种不同类型许可证的付款数据。我正在发送我的许可证的 IEnumerable。它包含 3 个空许可证。
澄清:最终用户可以拥有 1、2 或 3 个许可证,每个许可证的类型都是唯一的——“钓鱼”、“划船”或“特许权”。
我围绕这个概念构建了视图:
<div class="form-group row">
<div class="col-md-2" align="right" style="padding-top:5px">
<strong>@Html.LabelFor(model => model.FirstOrDefault().Notes, "Notes:", htmlAttributes: new { @class = "control-label" })</strong>
</div>
<div class="col-md-9">
<div class="row">
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Skip(1).Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Skip(1).Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
<div class="col-md-4" align="left">
@Html.EditorFor(model => model.Skip(2).Take(1).FirstOrDefault().Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Skip(2).Take(1).FirstOrDefault().PermitTypeId, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
客户为每个适当的支付类型输入数据,保存按钮将数据发回,我检查每个支付类型是否不为空,然后照常处理。
这样做正确吗?有没有更好的方法?
如有任何意见,我们将不胜感激。
此致, 迦太基
您可以在标记中使用 foreach
循环来遍历可枚举对象。
<div class="form-group row">
<div class="col-md-2" align="right" style="padding-top:5px">
<strong>@Html.LabelFor(model => model.FirstOrDefault().Notes, "Notes:", htmlAttributes: new { @class = "control-label" })</strong>
</div>
<div class="col-md-9">
<div class="row">
foreach (var item in Model)
{
<div class="col-md-4" align="left">
@Html.EditorFor(modelItem => item.Notes, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(modelItem => item.PermitTypeId, "", new { @class = "text-danger" })
</div>
}
</div>
</div>
</div>
无法通过索引直接访问IEnumerable。您可以使用的更具可读性的循环语句是 foreach,然后使用 if 语句检查 ID。
由于此搜索的最复杂度为 O(n),因为它必须针对每个项目进行循环,因此 forach 解决方案对我来说没问题。
我不完全了解您的代码库或模型,但如果您仅在其中一个 ID 为 null 时验证失败,那么以下代码将是我最好的收获:
private bool ValidateCollection(IEnumerable<Item> itemsCollction)
{
foreach(Item item in itemsCollction)
{
if(item.ID == null)
return false; // At least one of the elements have ID null.
}
return true;
}
只想说: 也可以使用 LINQ,但平均情况下执行速度远低于 foreach,因为 LINQ 查询会产生大量开销。
您可以使用构造函数将枚举对象转换为数组或列表,但它仍然必须循环遍历集合中的每个项目。然后你可以使用 for 循环执行比 foreach 更好的数组,但这只有在你经常重用第一次转换的结果时才有用。否则,您将浪费时间将 IEnumerable 转换为列表或数组。