【问题标题】:MVC and Entity Framework Select ListMVC 和实体框架选择列表
【发布时间】:2013-07-30 20:46:20
【问题描述】:

我有一个 MVC 应用程序,我正在尝试将它放在一起,它需要一些选择列表和下拉列表。

所以,我有以下模型......

public class Task
{
    public int ID { get; set; }
    public string Title { get; set; }
    ......
    public virtual ICollection<Monitor> Monitors { get; set; }
    public virtual ICollection<Resource> Resources { get; set; }

}
public class Monitor
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public IList<Task> Tasks { get; set; }
}
    public class Resource
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    .....

    public IList<Task> Tasks { get; set; }

有趣的部分是,当我显示任务列表时,在显示正常的其他属性中,我需要显示分配给任务的“监视器”列表和“资源”列表索引视图如下所示。

@model IEnumerable<ResourceManager.Models.Task>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        .....
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        .....
        <th>
            @Html.DisplayNameFor(model => model.Monitors)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Resources)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        .....
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        .....
        <td>
            @if (item.Monitors == null || item.Monitors.Count == 0) 
                 {<span>No Monitors Assigned</span>}
            else 
                 { string.Join(", ", item.Monitors.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName))); }
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Resources)
        </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>

这里是控制器....

    public ActionResult Index()
    {
        var tasks = from t in db.Tasks where t.IsActive == true select t;
        return View(tasks);
    }

我希望监视器列表和资源列表在索引、删除和详细信息视图上显示为字符串,即“监视器 1、监视器 2、监视器 3”和“资源 1、资源 2、资源 3” '。

但是在其他视图(创建和编辑)上,我希望它们显示为可选列表。

【问题讨论】:

  • 你想在哪里存储选定的监视器或选定的资源?
  • 我有一个用于监视器、任务和资源的表,其中包含用于 TaskMonitor 和 TaskResources 的交叉链接表

标签: asp.net asp.net-mvc entity-framework


【解决方案1】:

首先在您的控制器中创建选择列表,

var monitor = //你的 linq 查询 ViewData["ddlList"] = 监视器 .Select(x => new SelectListItem { 文本 = x.FirstName, 值 = x.Id.ToString() }).ToList();

然后你可以在你的视图中使用它,如下所示,

<%=Html.DropDownList("myList") %>

【讨论】:

  • 我要试试这个列表。我会告诉你结果如何。
  • 好的,所以 var allMonitors 正在从 db 返回所有监视器,但是当它尝试创建 ViewData 时出现错误,说“LINQ to Entities 无法识别方法'System. String ToString()' 方法,该方法不能翻译成 store 表达式。"
【解决方案2】:

对于监视器/资源的显示(并且由于您希望它们显示为逗号分隔的列表),您可以使用string.Join

<td>
    @string.Join(",", Model.Monitors.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName)))
</td>

为了能够实际使用Html.DisplayFor,您必须创建一个自定义显示模板,以便 Razor 真正知道如何响应。为此,在您的 Views 文件夹中,创建名为“DisplayTemplates”的新文件夹,并在其中创建一个名为“Monitors.cshtml”和“Resources.cshtml”的新局部视图,强类型为IEnumerable&lt;Monitor&gt;IEnumerable&lt;Resource&gt; , 分别。然后在该文件中,您只需添加与上面大致相同的代码:

@model IEnumerable<Monitor>

@string.Join(",", Model.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName)))

那么在你看来,你可以调用:

@Html.DisplayFor(m => m.Monitors, "Monitors")

不幸的是,在此示例中,您必须提供模板名称,因为DisplayFor 对于列表的默认行为是多次呈现显示模板,列表中的每个成员一次。您可以执行以下操作:

# Monitor.cshtml

@model Monitor

@Model.FirstName @Model.LastName,

然后:

@Html.DisplayFor(m => m.Monitors)

但你的最后一个项目的末尾会有一个逗号。

要编辑列表,您只需将选择列表传递到您的视图即可。最理想的情况是,您可以使用视图模型来执行此操作,但为简单起见,我将在此处使用 ViewBag。在您的控制器操作中:

ViewBag.MonitorChoices = db.Monitors.Select(m => new SelectListItem
    {
        Value = m.ID.ToString(),
        Text = string.Format("{0} {1}", m.FirstName, m.LastName)
    });

然后,在您的创建/编辑视图中:

@Html.ListBoxFor(m => m.Monitors, ViewBag.MonitorChoices)

【讨论】:

  • 你的回答很详细!干杯。
  • 我要试试这个,让你知道它是如何工作的。很棒的反应!
  • 这对于索引和详细信息视图非常有效。我在惰性绑定方面遇到了问题。即使它们在数据库中,我的监视器也会返回 null。
  • 您的导航属性应为virtual ICollections,即public virtual ICollection&lt;Monitor&gt; Monitors { get; set; }
  • 好的,修复了惰性绑定,但现在显示的另一个问题...我看到正在创建字符串(在这种情况下,我分配了 2 个监视器),但它没有显示.我更新了上面的代码
【解决方案3】:

如下尝试,

var monitor = //你的 linq 查询 列表监视器列表 = 新列表(); foreach(监视器中的 var 监视器){ SelectListItem 项 = 新的 SelectListItem(); item.Text = monitor.FirstName; item.Value = monitor.Id.ToString(); 监视器列表 .Add(item); } ViewData["ddlList"] = monitorList;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    相关资源
    最近更新 更多