C# 将前5行的LINQ分组和排序放入ViewModel列表

C# 将前5行的LINQ分组和排序放入ViewModel列表,c#,sql,linq,visual-studio-2013,asp.net-mvc-5,C#,Sql,Linq,Visual Studio 2013,Asp.net Mvc 5,我正在尝试为我的垒球网络应用程序创建一个新的前五大热门排行榜。我是MVC新手,我很难将这个查询放在一起并将信息传递给我的ViewModel。如果可能的话,我想在控制器中使用非查询调用,比如var results。我正试图在统计表中按球员ID对AtBats进行分组。我还希望能够从我的视图中的player表中为这个列表调用player的FirstName和LastName。谢谢你的帮助 在Stat.cs中 using System; namespace TheFlyingPig.Models {

我正在尝试为我的垒球网络应用程序创建一个新的前五大热门排行榜。我是MVC新手,我很难将这个查询放在一起并将信息传递给我的ViewModel。如果可能的话,我想在控制器中使用非查询调用,比如var results。我正试图在统计表中按球员ID对AtBats进行分组。我还希望能够从我的视图中的player表中为这个列表调用player的FirstName和LastName。谢谢你的帮助

在Stat.cs中

using System;

namespace TheFlyingPig.Models
{
    public class Stat
    {
        public int StatID { get; set; }
        public int SeasonID { get; set; }
        public int PlayerID { get; set; }
        public DateTime GameDate { get; set; }
        public int AtBats { get; set; }
        public int Hits { get; set; }
        public int Walks { get; set; }
        public int Singles { get; set; }
        public int Doubles { get; set; }
        public int Triples { get; set; }
        public int HomeRuns { get; set; }
        public int RBIs { get; set; }
        public int Runs { get; set; }
        public int ReachedOnErrors { get; set; }
        public int SacrificeFlies { get; set; }

        public virtual Season Season { get; set; }
        public virtual Player Player { get; set; }
    }
}
在Player.cs中

using System;
using System.Collections.Generic;

namespace TheFlyingPig.Models
{
    public class Player
    { 
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public virtual ICollection<Stat> Stats { get; set; }
    }
}
“群比”的原因是什么?在我看来,您所需要做的就是从db.Stats中选择按点击数降序排列的前5行。像这样:

var results = (
    from s in db.Stats
    join p in db.Players on s.PlayerID equals p.ID
    where s.SeasonID == lastSeasonId
    order by s.Hits descending
    select new { Player = p, Stats = s })
    .Take(5).ToList();
**我假设统计数据中的每一行代表一年

编辑:

好的,每个统计对象代表第一次错过的一场比赛。如果您希望统计数据按年份汇总,那么您的查询中缺少的部分是命中率的总和,可能还有其他统计数据。此查询将提供按点击总数排名的前5个赛季,以及与之相关的赛季和球员

var hitLeaders = (from s in stats
                  join p in players on s.PlayerID equals p.ID
                  group s by new { s.PlayerID, s.SeasonID } into g
                  select new 
                  { 
                     PlayerID = g.Key.PlayerID, 
                     SeasonID = g.Key.SeasonID, 
                     Hits = g.Sum(sum => sum.Hits),
                     AtBats = g.Sum(sum => sum.AtBats),
                     Walks = g.Sum(sum => sum.Walks),
                     Singles = g.Sum(sum => sum.Singles),
                     Doubles = g.Sum(sum => sum.Doubles),
                     Triples = g.Sum(sum => sum.Triples),
                     HomeRuns = g.Sum(sum => sum.HomeRuns),
                     RBIs = g.Sum(sum => sum.RBIs),
                     Runs = g.Sum(sum => sum.Runs),
                     ReachedOnErrors = g.Sum(sum => sum.ReachedOnErrors),
                     SacrificeFlies = g.Sum(sum => sum.SacrificeFlies)
                  }).OrderByDescending(s => s.Hits).Take(5);
现在,您将遇到的第二个问题是,您无法将此查询的结果分配给视图模型,因为它会生成IEnumerable,但视图模型需要一个列表。我的建议是创建一个对象,该对象表示一名球员一年内的总统计数据;大概是这样的:

public class TotalStat
{
    public int TotalStatID { get; set; }
    public int SeasonID { get; set; }
    public int PlayerID { get; set; }
    public int AtBats { get; set; }
    public int Hits { get; set; }
    public int Walks { get; set; }
    public int Singles { get; set; }
    public int Doubles { get; set; }
    public int Triples { get; set; }
    public int HomeRuns { get; set; }
    public int RBIs { get; set; }
    public int Runs { get; set; }
    public int ReachedOnErrors { get; set; }
    public int SacrificeFlies { get; set; }
}
然后,只需将视图模型更改为:

public List<TotalStat> SeasonLeadersHits { get; set; }

错误表示它无法将类型“System.Linq.IQueryable”隐式转换为“System.Collections.Generic.List”。存在显式转换您是否缺少演员阵容?您的属性是List SeasonalLeadershits,但您所有的查询都在创建匿名类型select语句,而不是typeof Stat。Stephen,我在网上看到了这个解释,但我不知道如何修复它。我如何才能将其添加到我的TeamStat视图模型中?我需要GroupBy,因为每个球员在赛季中都可以有多个统计数据。我需要每个球员ID的赛季总数,然后按点击率降序排列。效果很好,但我必须将公共列表季节领导权{get;set;}更改为公共IEnumerable季节领导权{get;set;}才能工作。非常感谢你!
var hitLeaders = (from s in stats
                  join p in players on s.PlayerID equals p.ID
                  group s by new { s.PlayerID, s.SeasonID } into g
                  select new 
                  { 
                     PlayerID = g.Key.PlayerID, 
                     SeasonID = g.Key.SeasonID, 
                     Hits = g.Sum(sum => sum.Hits),
                     AtBats = g.Sum(sum => sum.AtBats),
                     Walks = g.Sum(sum => sum.Walks),
                     Singles = g.Sum(sum => sum.Singles),
                     Doubles = g.Sum(sum => sum.Doubles),
                     Triples = g.Sum(sum => sum.Triples),
                     HomeRuns = g.Sum(sum => sum.HomeRuns),
                     RBIs = g.Sum(sum => sum.RBIs),
                     Runs = g.Sum(sum => sum.Runs),
                     ReachedOnErrors = g.Sum(sum => sum.ReachedOnErrors),
                     SacrificeFlies = g.Sum(sum => sum.SacrificeFlies)
                  }).OrderByDescending(s => s.Hits).Take(5);
public class TotalStat
{
    public int TotalStatID { get; set; }
    public int SeasonID { get; set; }
    public int PlayerID { get; set; }
    public int AtBats { get; set; }
    public int Hits { get; set; }
    public int Walks { get; set; }
    public int Singles { get; set; }
    public int Doubles { get; set; }
    public int Triples { get; set; }
    public int HomeRuns { get; set; }
    public int RBIs { get; set; }
    public int Runs { get; set; }
    public int ReachedOnErrors { get; set; }
    public int SacrificeFlies { get; set; }
}
public List<TotalStat> SeasonLeadersHits { get; set; }
//...
group s by new { s.PlayerID, s.SeasonID } into g
select new TotalStat
{ 
    PlayerID = g.Key.PlayerID, 
//...