我遇到了一个问题,我在控制器中进行了以下查询:
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.IEnumerable1[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(我暂时无法发布图片)
感谢您抽出时间,英语不是我的第一语言。
答案 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 Models和http://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)
};