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)
答案 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()
执行数据库调用。并将值传递回视图。