2014-01-06 60 views
6

我想在一个视图中使用两个模型,但是从我理解我的程序只是看不到模型内的任何对象。如何在一个视图中使用两个IENUMrable模型

这是我的代码。

型号:

public class Album 
    { 
     [Key] 
     public int ThreadId { get; set; } 
     public int GenreId { get; set; } 
     public string Title { get; set; } 
     public string ThreadByUser { get; set; } 
     public string ThreadCreationDate { get; set; } 
     public string ThreadContent { get; set; } 
     public Genre Genre { get; set; } 
     public List<Posts> Posty { get; set; } 
    } 
    public class Posts 
    { 
     [Key] 
     public int PostId { get; set; } 
     public int ThreadId { get; set; } 
     public string PostTitle { get; set; } 
     public string PostContent { get; set; } 
     public string PostDate { get; set; } 
     public string PosterName { get; set; } 
     public Album Album { get; set; } 

    } 

    public class ModelMix 
    { 
     public IEnumerable<Posts> PostsObject { get; set; } 
     public IEnumerable<Album> ThreadsObject { get; set; } 
    } 

指数控制器代码:

public ActionResult Index(int id) 
    { 

     ViewBag.ThreadId = id; 
     var posts = db.Posts.Include(p => p.Album).ToList(); 
     var albums = db.Albums.Include(a => a.Genre).ToList(); 

     var mixmodel = new ModelMix 
     { 
      PostsObject = posts, 
      ThreadsObject = albums 
     }; 

     return View(mixmodel); 
    } 

查看代码:

@model MvcMusicStore.Models.ModelMix 

<h2>Index</h2> 

@Html.DisplayNameFor(model => model.PostsObject.PostContent) 

当我尝试执行我的计划,我得到这个错误:

CS1061: The " System.Collections.Generic.IEnumerable 'does not contain a definition of" PostContent "not found method of expanding" PostContent ", which takes a first argument of type' System.Collections.Generic.IEnumerable "

我如何使它按预期工作?在互联网上有很多像我这样的问题,但我找不到与我的情况相符的问题。

+0

需要迭代它们在\的foreach –

回答

6

循环模型在MVC中可能有点令人困惑,仅仅是因为模板助手(即, Html.DisplayForHtml.EditorFor)可以提供模板,帮助者将自动调用集合中的每个元素。这意味着,如果你是新来的MVC,和你没有意识到一个DisplayTemplateEditorTemplate尚未规定的收集已经,它看起来好像简单:

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

是你所需要的。所以如果你已经看到过这样的事情,那可能就是你为什么会这么做的原因。不过,我们假设暂时还没有提供模板。你有两个选择。

首先,最简单地说,就是使用foreach在集合:

@foreach (var post in Model.PostsObject) 
{ 
    @Html.DisplayFor(m => post.PostTitle) 
    // display other properties 
} 

您也可以使用for循环,但IEnumerable<T>,没有索引,所以这是行不通的:

@for (int i = 0; i < Model.PostsObject.Count(); i++) 
{ 
    // This generates a compile-time error because 
    // the index post[i] does not exist. 
    // This syntax would work for a List<T> though. 
    @Html.DisplayFor(m => post[i].PostTitle) 
    // display other properties 
} 

如果你确实想使用for循环是,你可以使用它像这样:

@for (int i = 0; i < Model.PostsObject.Count(); i++) 
{ 
    // This works correctly 
    @Html.DisplayFor(m => post.ElementAt(i).PostTitle) 
    // display other properties 
} 

所以请使用你喜欢的任何一个。但是,在某些时候,查看提供templates for your types是个好主意。 (注意:虽然本文是为MVC 2编写的,但建议仍然适用。)它们允许您从视图中删除循环逻辑,使其更清晰。当与Html.DisplayForHtml.EditorFor结合使用时,它们也将为模型绑定生成正确的元素命名(这很好)。他们还允许您重复使用某种类型的演示文稿。

最后一个评论我要提出的是,你的属性的命名有点冗长:

public class ModelMix 
{ 
    public IEnumerable<Posts> PostsObject { get; set; } 
    public IEnumerable<Album> ThreadsObject { get; set; } 
} 

我们已经知道他们的对象,所以没有必要添加的结束。这是更具可读性:

public class ModelMix 
{ 
    public IEnumerable<Posts> Posts { get; set; } 
    public IEnumerable<Album> Threads { get; set; } 
} 
+1

非常感谢,我用foreach循环去了。我不知道我的问题的解决方案将如此简单! – user3163730

+0

@ user3163730不客气。 :) –

0

您需要遍历他们是这样的:

@model MvcMusicStore.Models.ModelMix 

<h2>Index</h2> 

@for(var i=0; i<model.PostsObject.Count(); i++) 
{ 
    @Html.DisplayNameFor(model => model.PostsObject[i].PostContent) 
} 

而且还最好是保存的IList,而不是IEnumerable的,因为这将有Count属性,而不是使用COUNT()方法

+0

DisplayNameFor将只显示标题,而不是实际的数据。这些通常用于表格的标题。 –

+0

是的,我知道。但原来的问题是关于DisplayNameFor方法,所以用它做了样本 –

+0

听起来对我很好! –

-1

通常你如果您传递任何类型的IEnumerable<>,则需要遍历每个项目。由于您构建了一个半复杂模型,因此您需要在每个列表中显示foreach项目。下面是从ASP.NET MVC的教程,我认为会帮助你有点基础的例子:

@model IEnumerable<ContosoUniversity.Models.Course> 

@{ 
    ViewBag.Title = "Courses"; 
} 

<h2>Courses</h2> 

<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table class="table"> 
    <tr> 
     <th> 
      @Html.DisplayNameFor(model => model.CourseID) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Title) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Credits) 
     </th> 
     <th> 
      Department 
     </th> 
     <th></th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.DisplayFor(modelItem => item.CourseID) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Title) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Credits) 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Department.Name) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.CourseID }) | 
      @Html.ActionLink("Details", "Details", new { id=item.CourseID }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.CourseID }) 
     </td> 
    </tr> 
} 

</table> 

通常大多数人使用的ICollection对他们的名单,其中一个例子可能是在一个对象:

public virtual ICollection<Post> Posts { get; set; } 

来源: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application

我会建议从头开始,因为它会帮助你理解为什么你需要这样做: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc

+0

这适用于我只有一个模型时,我确实已经知道该如何工作(我认为),我已经完成了该网站的教程(但对于mvc4--您制作电影数据库的那个教程),但它们未包括在内在一个视图中有两个模型的任何示例。 – user3163730

+0

您可以简单地从复杂对象中决定想要的模型。 I.E. Model.Object1.Whatever/Model.Object2.Whatever –

相关问题