C# 如何在lambda表达式mvc中使用selectmany
我在MVC应用程序中有以下lambda表达式。我想对数据进行分组C# 如何在lambda表达式mvc中使用selectmany,c#,asp.net-mvc,entity-framework-4,lambda,C#,Asp.net Mvc,Entity Framework 4,Lambda,我在MVC应用程序中有以下lambda表达式。我想对数据进行分组 var toprating= _db.Movie.SelectMany(m => m.Rating.Select(r=> new { movieID=r.MovieID, MovieTitle= m.Title })).GroupBy(m=>m.movieID).ToList(); ViewBag.
var toprating= _db.Movie.SelectMany(m => m.Rating.Select(r=> new
{
movieID=r.MovieID,
MovieTitle= m.Title
})).GroupBy(m=>m.movieID).ToList();
ViewBag.TopMovie = toprating;
}
我想把这个传递给我的观点。
在我看来,我试着写以下几点
IEnumerable<Movie> TopMovies = ViewBag.TopMovie;
但我犯了这个错误
Cannot implicitly convert type 'object' to 'System.Collections.Generic.IEnumerable<Movie>'. An explicit conversion exists (are you missing a cast?)
将提供任何帮助。ViewBag是一个动态对象。这是.NET 4.0引入的功能,因此.NET不知道对象上的任何属性是什么类型。由于.NET不知道该类型,如果要将任何属性存储在变量中,则必须显式强制转换ViewBag上的属性
var topMovies = ViewBag.TopMovie as IEnumerable<Movie>;
要将任何内容转换为电影类型,您需要更改原始LINQ查询以选择电影而不是匿名类型。ViewBag是动态对象.NET 4.0引入的一项功能,因此.NET不知道对象上的任何属性是什么类型。由于.NET不知道该类型,如果要将任何属性存储在变量中,则必须显式强制转换ViewBag上的属性
var topMovies = ViewBag.TopMovie as IEnumerable<Movie>;
要将任何内容转换为电影类型,您需要更改原始LINQ查询以选择电影而不是匿名类型。这是因为SelectMany和GroupBy中的匿名对象 GroupBy不返回IEnumerable,而是返回每个子集合具有相同键值的集合的集合 在这种情况下,按电影Id进行分组会得到一个相当奇怪的集合:
toprating: [
[
// MovieID, Movie Title
{ 1, Movie1Title }, // one Id/title pair for every rating.
{ 1, Movie1Title },
{ 1, Movie1Title },
...
],
[
{ 2, Movie2Title }, // one title for every rating.
{ 2, Movie2Title },
{ 2, Movie2Title },
...
]
]
类似的,但如果这真的是你想要的,好吧。那么在你看来,你正在尝试这样做:
IEnumerable<Movie> TopMovies = ViewBag.TopMovie;
但顶级电影是数不清的。所以当然,它不能投给电影
这将为您提供对象,并允许您在其上枚举:
IEnumerable<IGrouping<int, object>> TopMovies = ViewBag.TopMovie;
虽然我怀疑这不是您真正想要做的,但如果没有更多信息,我也无能为力。这是因为SelectMany和GroupBy中的匿名对象 GroupBy不返回IEnumerable,而是返回每个子集合具有相同键值的集合的集合 在这种情况下,按电影Id进行分组会得到一个相当奇怪的集合:
toprating: [
[
// MovieID, Movie Title
{ 1, Movie1Title }, // one Id/title pair for every rating.
{ 1, Movie1Title },
{ 1, Movie1Title },
...
],
[
{ 2, Movie2Title }, // one title for every rating.
{ 2, Movie2Title },
{ 2, Movie2Title },
...
]
]
类似的,但如果这真的是你想要的,好吧。那么在你看来,你正在尝试这样做:
IEnumerable<Movie> TopMovies = ViewBag.TopMovie;
但顶级电影是数不清的。所以当然,它不能投给电影
这将为您提供对象,并允许您在其上枚举:
IEnumerable<IGrouping<int, object>> TopMovies = ViewBag.TopMovie;
虽然我怀疑这不是您真正想要做的,但如果没有更多信息,我也无能为力。您传递的集合类型不是IEnumerable。请注意,您使用的是匿名类型,然后还使用了GroupBy。结果类型很复杂 您的查询也是毫无意义的,因为您正在访问评级,但没有使用它,因此您可能会得到同一部电影的多个副本,并且所有评级信息都被丢弃。目前,我假设你真的希望收视率包括在内 因此,您可以使用以下查询,例如:
ViewBag.Ratings = _db.Movie.SelectMany(m => m.Rating.Select(r => new
{
Movie = m,
Rating = r
})).GroupBy(m => m.Movie, m => m.Rating).ToList();
现在,上述查询的类型是List,因此您可以在视图中使用它:
List<IGrouping<Movie, Rating>> ratings = ViewBag.Ratings;
您传递的集合类型不是IEnumerable。请注意,您使用的是匿名类型,然后还使用了GroupBy。结果类型很复杂 您的查询也是毫无意义的,因为您正在访问评级,但没有使用它,因此您可能会得到同一部电影的多个副本,并且所有评级信息都被丢弃。目前,我假设你真的希望收视率包括在内 因此,您可以使用以下查询,例如:
ViewBag.Ratings = _db.Movie.SelectMany(m => m.Rating.Select(r => new
{
Movie = m,
Rating = r
})).GroupBy(m => m.Movie, m => m.Rating).ToList();
现在,上述查询的类型是List,因此您可以在视图中使用它:
List<IGrouping<Movie, Rating>> ratings = ViewBag.Ratings;
是ViewBag.TopMovie对象上的类型吗?您可能需要更改其类型或将其强制转换为IEnumerable。ViewBag.TopMovie对象上的类型是否可能重复?您可能需要更改其类型或将其强制转换为IEnumerable。我认为可能的重复是因为选择了new。movieID=MovieTitle=没有定义类型您在原始查询中真正想要选择的是什么?为所有电影选择所有收视率似乎很奇怪。你需要每部电影的平均收视率吗?我想这是因为选择了新的。movieID=MovieTitle=没有定义类型您在原始查询中真正想要选择的是什么?为所有电影选择所有收视率似乎很奇怪。你需要每部电影的平均评分吗?这是正确的答案,但我希望电影只出现一次,并按最高评分顺序打印。如果最高评级的电影是5次,让它排名第一,然后是4次,以此类推。thanks@JED:是的,所以您希望使用.Count来确定分级的数量,使用.OrderByDescending来按其排序:谢谢,我终于用下面的代码var toprating=\u db.Movie解决了这个问题。选择manym=>m.Rating。
GroupByt=>t.Movie.Selectr=>new AssingTopMovieRating{MovieId=m.MovieId,MovieTitle=m.Title,CountMovieId=r.Count}.OrderByDowningr=>r.CountMovieId@杰德:干得好:虽然我个人建议称它为“评级”或“评级计数”,而不是“CountMovieId”,也许你也应该重新考虑这个类的名称——我的意思是“assing”?什么?杰德:我还是不知道为什么里面有“分配”这个词。类型名称应为名词或名词短语。如果类型封装了一个电影分级,也许它应该被称为只是电影分级?这是正确的答案,但我希望电影只出现一次,并按最高分级的顺序打印。如果最高评级的电影是5次,让它排名第一,然后是4次,以此类推。thanks@JED:是的,所以您希望使用.Count来确定分级的数量,使用.OrderByDescending来按其排序:谢谢,我终于用下面的代码var toprating=\u db.Movie解决了这个问题。SelectManym=>m.Rating.GroupByt=>t.Movie.Selectr=>new AssingTopMovieRating{MovieId=m.MovieId,MovieTitle=m.Title,CountMovieId=r.Count}.orderbydowningr=>r.CountMovieId@杰德:干得好:虽然我个人建议称它为“评级”或“评级计数”,而不是“CountMovieId”,也许你也应该重新考虑这个类的名称——我的意思是“assing”?什么?杰德:我还是不知道为什么里面有“分配”这个词。类型名称应为名词或名词短语。如果类型封装了一个电影分级,也许应该称之为仅仅是电影分级?