asp.net-mvc 如何在一个视图中使用两个 IENumerable 模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20953877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:25:29  来源:igfitidea点击:

How to use two IENumerable models in one view

asp.net-mvcasp.net-mvc-4modelienumerable

提问by user3163730

I am trying to use two models in one view, but from what I understand my program just don't see any objects within models.

我试图在一个视图中使用两个模型,但据我所知,我的程序在模型中看不到任何对象。

Here is my code.

这是我的代码。

Models:

楷模:

    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; }
    }  

Index controller code:

索引控制器代码:

    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);
    }

View code:

查看代码:

@model MvcMusicStore.Models.ModelMix

<h2>Index</h2>

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

And when I try to execute my program I am getting this error:

当我尝试执行我的程序时,我收到此错误:

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 "

CS1061:“System.Collections.Generic.IEnumerable”不包含“PostContent”的定义,未找到扩展“PostContent”的方法,该方法采用“System.Collections.Generic.IEnumerable”类型的第一个参数

How I can make it work as intended? There are a lot of questions like mine on the internet but I couldn't find any matching my case.

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

回答by John H

Looping over models can be a little confusing to begin with in MVC, only because the templated helpers (i.e. Html.DisplayForand Html.EditorFor) can be provided templates which the helper will automatically invoke for every element in a collection. That means if you're new to MVC, and you don't realise a DisplayTemplateor an EditorTemplatehas not been provided for the collection already, it looks as though a simple:

在 MVC 中循环模型可能会有点令人困惑,这只是因为可以为模板化助手(即Html.DisplayForHtml.EditorFor)提供模板,助手将自动为集合中的每个元素调用这些模板。这意味着如果您是 MVC 的新手,并且您没有意识到 aDisplayTemplate或 anEditorTemplate尚未为集合提供,它看起来好像很简单:

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

is all you need. So if you've seen something like that already, that might be why you made the assumption it would work. However, let's assume for a moment that a template has not been provided. You have two options.

是你所需要的全部。因此,如果您已经看到过类似的东西,那可能就是您假设它会起作用的原因。但是,让我们暂时假设尚未提供模板。你有两个选择。

Firstly, and most simply, would be to use foreachover the collection:

首先,也是最简单的,就是foreach在集合上使用:

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

You could also use a forloop, but with IEnumerable<T>, there is no indexer, so this won't work:

你也可以使用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
}

If you did want to use the forloop still, you can use it like so:

如果你仍然想使用for循环,你可以像这样使用它:

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

So use whichever you prefer. However, at some point it would be a good idea to look into providing templates for your types. (Note: Although this article was written for MVC 2, the advice still applies.) They allow you to remove looping logic from your views, keeping them cleaner. When combined with Html.DisplayFor, or Html.EditorFor, they will also generate correct element naming for model binding (which is great). They also allow you to reuse presentation for a type.

所以使用你喜欢的任何一个。但是,在某些时候,考虑为您的类型提供模板是个好主意。(注意:虽然本文是为 MVC 2 编写的,但建议仍然适用。)它们允许您从视图中删除循环逻辑,使它们更干净。当与Html.DisplayFor, 或结合使用时Html.EditorFor,它们还将为模型绑定生成正确的元素命名(这很棒)。它们还允许您重用类型的表示。

One final comment I'd make is that the naming of your properties is a little verbose:

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

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

We already know they're objects, so there's no need to add that on the end. This is more readable:

我们已经知道它们是对象,所以没有必要在最后添加它。这更具可读性:

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

回答by Sergey Litvinov

You need to iterate them like this:

您需要像这样迭代它们:

@model MvcMusicStore.Models.ModelMix

<h2>Index</h2>

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

And also it's better to save IList instead of IEnumerable, as it will have Count property, instead of using Count() method

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

回答by Jon Douglas

Typically you'll need to iterate through each item if you're passing in any type of IEnumerable<>. Since you built a semi-complex model, you'll want to display foreachitem in each list. Here is an example based from the ASP.NET MVC tutorials that I think would help you a bit:

通常,如果您传入任何类型的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>

Generally most people use an ICollectionfor their lists, where an example might be in an object:

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

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

Source: 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/reading-related-data-with-the-entity-framework-in-an-asp-net- mvc-应用程序

I would recommend starting at the beginning as it'll help you understand why you need to do this: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc

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