在索引上显示其他模型的信息

时间:2014-11-11 09:21:17

标签: c# asp.net-mvc

Noob警告 - 学习学术项目的MVC : - )

我有两个模型,我试图在Actors的索引视图中显示ProjectName(来自第一个模型)(来自我的第二个模型)。一切都加载好了,我可以从我的Actor类中显示projectId,但它没有在我的索引表中为@Html.DisplayFor(modelItem => item.project.ProjectName)获取值。

然而,它正在拾取表中的正确[DisplayName("Project Name"),这让我觉得它正在建立一些连接 - 只是无法理解为什么它没有得到它的值,我只是有一个空列标记正确的标题!

我曾计划使用ViewModel来实现这一目标,但在Wrox Professional ASP.NET MVC 4书中,作者做了与我试图展示的类型相同的内容。专辑视图(MVC音乐商店项目 - http://www.asp.net/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-4)中的艺术家姓名(不是ID)。

非常感谢!

 public class Project
{
    public int ID {get; set;}
    [DisplayName ("Project Name")]
    public string ProjectName { get; set; }
    [DisplayName("Client")]    
    public string ClientID { get; set; }
    public string Description { get; set; }
    [DisplayName("Use Cases")]
    public virtual ICollection <UseCase> UseCases { get; set; } 

}

...

 public class Actor
{
    public int ID { get; set; }
    public int projectID { get; set; }
    public Project project { get; set; } 
    public string Title { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
}

这是我的索引操作的控制器代码(注意,我在URL中传递projectId,这就是我用作参数...

// GET: Actors
    public ActionResult Index(int? id)
    {
        ViewBag.projectId = id;
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        else
        {
            return View(db.Actors.Where(x => x.projectID == id).ToList());
        }
    }

这是视图代码....

   @model IEnumerable<JustSpecIt.Models.Actor>
@{
    ViewBag.Title = "Actors";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Actors</h2>

<p>
    @Html.ActionLink("Create New", "Create", new { id = ViewBag.projectId })
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.project.ProjectName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.projectID)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.project.ProjectName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.projectID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </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>

@Html.ActionLink("<< Back", "ShowSteps", "Projects", new { id = ViewBag.projectId }, null)

2 个答案:

答案 0 :(得分:2)

尝试将virtual关键字添加到project类中的Actor属性,以允许延迟加载相关的Project

public class Actor
{
    public int ID { get; set; }
    public int projectID { get; set; }
    public virtual Project project { get; set; } 
    public string Title { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
}

有关延迟加载相关实体的更多信息,请参阅此处:http://msdn.microsoft.com/en-us/data/jj574232#lazy

答案 1 :(得分:0)

public class Project
{
    public int ID {get; set;}
    [DisplayName ("Project Name")]
    public string ProjectName { get; set; }
    [DisplayName("Client")]    
    public string ClientID { get; set; }
    public string Description { get; set; }
    [DisplayName("Use Cases")]
    public virtual ICollection <UseCase> UseCases { get; set; } 
}

public class Actor
{
    public int ID { get; set; }
    public int projectID { get; set; }
    public virtual Project project { get; set; } 
    public string Title { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
}

// GET: Actors
public ActionResult Index(int? id)
{
    ViewBag.projectId = id;
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }


    using (var context = new DbContext()) // initiate a connection to the DB
    {
        var actors = context.Actors.Where(x => x.projectID == id);

        // tell it to include the projects
        actors.Include("project"); // the name of the property

        // now retrieve list from the DB
        actors.ToList();

        // return the actors to the view
        return View(actors);
    }
 }

所以DbContext就是你调用上下文的东西。我们将它包装在一个使用中,以确保我们正确管理连接。

virtual前面的Project project {get;set;}关键字是启用延迟加载,在某些情况下可能会导致错误(导致SELECT N + 1问题)。为了确保我们在演员列表中包含所有项目,我们使用Include函数并传递属性的名称。

为了绕过SELECT N + 1的问题,我们在将值传递给视图之前调用ToList()方法。如果我们不这样做,那么视图将执行get actors SQL,并且对于每个actor,它将执行调用以获取项目。所以,如果我们有10个演员,我们将进行11次通话。哪个不好。 ToList()确保我们执行1次调用,为我们提供视图中所需的所有值。

然后我们用ToList()执行数据库调用。并将值传递回视图。