提问者:小点点

如何按ID访问IEnumerable模型的项2(或3或X)


我正在寻找一个最佳实践。我有一些有用的东西,但我不知道它是否“正确”。

我正在构建一个页面,客户可以为三种不同类型的许可证输入支付数据。我正在发送我的许可证的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>

客户为每种适当的支付类型输入数据,Save按钮将数据发回,我检查每种支付类型是否不为空,然后照常处理。

这样做对吗?有没有更好的办法?

如有任何投入,将不胜感激。

问候,Carthax


共2个答案

匿名用户

您可以在标记中使用循环来遍历枚举。

<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是空的,下面的代码将是我的最佳选择:

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转换为列表或数组就浪费了时间。