C# 如何在lambda表达式mvc中使用selectmany

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.

我在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.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”?什么?杰德:我还是不知道为什么里面有“分配”这个词。类型名称应为名词或名词短语。如果类型封装了一个电影分级,也许应该称之为仅仅是电影分级?