返回LINQ查询以查看并循环查看视图中的结果

时间:2013-11-03 16:43:19

标签: c# asp.net asp.net-mvc linq asp.net-mvc-4

我遇到了一个问题,我在控制器中进行了以下查询:

var query = from pmt in db.ProjectHasTags
            join project in db.Projects on pmt.ProjectId equals project.ID
            join tag in db.ProjectTags
                 on pmt.TagId equals tag.ID
                 group pmt by pmt.Project into pmtGroup
                    select new
                    {
                        Project = pmtGroup.Key,
                        Tags = pmtGroup.Select(project => project.ProjectTag)
                    };

我想使用以下命令将此查询返回给视图:

return View(query.ToList());

在视图文件中,我有以下代码:

@model IEnumerable<portfolio.Models.ProjectHasTag>

@foreach (var p in Model)
{
    @p.Project.Title

    foreach (var tag in p.Tags)
    {
        @tag.title
    }       
}

我收到以下错误:

  

传递到字典中的模型项的类型为'System.Collections.Generic.List 1[<>f__AnonymousType6 2 [portfolio.Models.Project,System.Collections.Generic.IEnumerable 1[portfolio.Models.ProjectTag]]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1 [portfolio。 Models.ProjectHasTag]”。

ProjectHasTag模型代码:

public class ProjectHasTag
{
    public int ID { get; set; }

    public int? ProjectId { get; set; }

    [ForeignKey("ProjectId")]
    [DisplayName("Project")]
    public virtual Project Project { get; set; }

    public int? TagId { get; set; }

    [ForeignKey("TagId")]
    [DisplayName("Tag")]
    public virtual ProjectTag ProjectTag { get; set; }

    public virtual ICollection<ProjectTag> Tags { get; set; }

}

这是我想要实现的目标: http://i.stack.imgur.com/DAZ5n.png(我暂时无法发布图片)

感谢您抽出时间,英语不是我的第一语言。

3 个答案:

答案 0 :(得分:4)

问题在于您的查询的这一部分:

select new
{
    Project = pmtGroup.Key,
    Tags = pmtGroup.Select(project => project.ProjectTag)
};

您没有指定应该实例化的类型,因此它创建了一个匿名类型,然后将其传递给您的视图。你可能想要这样的东西:

select new ProjectHasTag
{
    Project = pmtGroup.Key,
    Tags = pmtGroup.Select(project => project.ProjectTag)
};

<强>更新

正如错误告诉您的那样,ProjectHasTag没有Tags属性。看起来你想要的是这个:

select new ProjectHasTag
{
    Project = pmtGroup.Key,
    ProjectTag = pmtGroup.Select(project => project.ProjectTag)
};

然而,你有点不清楚你想要做什么,因为在你看来,你看起来每个项目都有多个标签,在这种情况下它应该是一个集合。类似的东西:

public virtual ICollection<ProjectTag> Tags { get; set; }

更新两个

我忘了实体框架(EF)在直接实例化实体类型时很挑剔。为了快速解决问题,您应该能够从匿名类型映射到实体类型(如here所述)。

然而,EF这样做实际上是一件好事,因为它迫使你采用一种设计策略,让你可以利用MVC的更多功能。特别是,这是了解ViewModel的好时机(请参阅:ASP.NET MVC - How exactly to use View Modelshttp://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx)。

答案 1 :(得分:0)

在查询的选择部分中,您将创建一个匿名对象,并且您的模型需要表单类型为ProjectHasTag的对象。所以这应该是(看select new ProjectHasTag):

var query = from pmt in db.ProjectHasTags
            join project in db.Projects on pmt.ProjectId equals project.ID
            join tag in db.ProjectTags
                 on pmt.TagId equals tag.ID
                 group pmt by pmt.Project into pmtGroup
                    select new ProjectHasTag
                    {
                        Project = pmtGroup.Key,
                        Tags = pmtGroup.Select(project => project.ProjectTag)
                    };

答案 2 :(得分:0)

由于你有一个ICollection,你告诉Linq,你希望你的ProjectTag是延迟加载的。就像上面提到的@John H一样,既然你已经将Tags属性添加到ProjectHasTag类中,你就可以填充它:

select new ProjectHasTag
{
    Project = pmtGroup.Key,
    Tags = pmtGroup.Select(project => project.ProjectTag)
};