C# 在集合上循环时,如何有效地将DropdownListFor绑定到嵌套类?

C# 在集合上循环时,如何有效地将DropdownListFor绑定到嵌套类?,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我正在努力找一个工作用的下拉列表。该系统为时间表系统,相关课程为周: public class Week { public int WeekId { get; set; } public List<TimeEntry> TimeEntries { get; set; } public Week() { TimeEntries = new List<TimeEntry>(); } } 每个时间条目都有一个账单状态(例

我正在努力找一个工作用的下拉列表。该系统为时间表系统,相关课程为

public class Week
{
    public int WeekId { get; set; }
    public List<TimeEntry> TimeEntries { get; set; }
    public Week()
    {
        TimeEntries = new List<TimeEntry>();
    }
}
每个
时间条目
都有一个
账单状态
(例如,已付款、待处理、已开票):

输入数据的方式来自WeekController。这有一系列行,数据库中的每个条目对应一行。还可以添加其他行,因此通过WeekController编辑/创建时间条目具有双重功能:

@Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                         new SelectList(ViewBag.BSID,
                        "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))

然而,我很难让BillingStatus的下拉列表正常工作。我想这是因为我是通过循环来渲染行的。然而,由于BillingStatus不是存储在
Week
类中,而是存储在
TimeEntry
类中,因此它变得更加复杂。(与我使用的控制器相比有点“低一级”)

如果我在DropDownList中为控件硬编码列表,它会工作:

@for (int i = 0; i < Model.TimeEntries.Count; i++)
{
    <div class="panel-body">
        <div class="index" style="display:none">@Model.TimeEntries[i].TimeEntryID</div>
        <div class="col-md-2">
            @Html.DropDownListFor(m => Model.TimeEntries[i].ClientID, (SelectList)ViewBag.ClientID, "Select...", new { style = "width:100%" })
        </div>
        <div class="col-md-2">
            @Html.DropDownListFor(m => Model.TimeEntries[i].TaskTypeID, (SelectList)ViewBag.TaskTypeID, "Select...", new { style = "width:100%" })
        </div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].MonHours, new { style = "width:100%", @class = "hours mon" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].TueHours, new { style = "width:100%", @class = "hours tue" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].WedHours, new { style = "width:100%", @class = "hours wed" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].ThuHours, new { style = "width:100%", @class = "hours thu" })</div>
        <div class="col-md-1">@Html.TextBoxFor(x => Model.TimeEntries[i].FriHours, new { style = "width:100%", @class = "hours fri" })</div>
        <div class="col-md-2">@Html.TextBoxFor(x => Model.TimeEntries[i].Comment)</div>
        <div class="col-md-1">
            @Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                 new SelectList(new List<Object>{
                                    new { BillingStatusID = 0 , Name = "Pending"  },
                                    new { BillingStatusID = 1 , Name = "Invoiced"  },
                                    new { BillingStatusID = 2 , Name = "Paid"  },
                 }, "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
        </div>
    </div>
}
并尝试在WeekController中使用ViewBag:

@Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                         new SelectList(ViewBag.BSID,
                        "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
但是这两种方法都不起作用。我还想确保我不是每次渲染一行时都要访问数据库,因为这看起来效率很低

我想我能做的就是得到这个:

new List<Object>{
    new { BillingStatusID = 0 , Name = "Pending"  },
    new { BillingStatusID = 1 , Name = "Invoiced"  },
    new { BillingStatusID = 2 , Name = "Paid"  },
    }
新列表{
新的{BillingStatusID=0,Name=“Pending”},
新的{BillingStatusID=1,Name=“invoited”},
新的{BillingStatusID=2,Name=“Paid”},
}
在加载页面时点击一次,然后使用SelectList将其环绕。但是,我不知道应该从何处获取它。我应该从控制器返回它吗


我对MVC还很陌生,所以我只是对ViewModels、ViewBags和EditorFor等概念有所了解-所以请假设我在回答时什么都不知道!!

您还没有展示您是如何尝试填充它的(无论是
BillingStatuses
还是
ViewBag.BSID
——您的模型甚至没有显示名为
BillingStatuses
的属性).无论如何,你的
Week
类应该包含一个属性
IEnumerable
,这样它只会被填充一次。酷-谢谢@StephenMuecke。这部分是我一直坚持的-它应该去哪里。(似乎对使用MVC的类有点“重新思考”)。
@Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
                         new SelectList(ViewBag.BSID,
                        "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
new List<Object>{
    new { BillingStatusID = 0 , Name = "Pending"  },
    new { BillingStatusID = 1 , Name = "Invoiced"  },
    new { BillingStatusID = 2 , Name = "Paid"  },
    }