如何通过 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 转换为列表或数组。