使用LINQ将累积平均值加载到MVC模型中

本文关键字:MVC 模型 加载 平均值 LINQ 使用 | 更新日期: 2023-09-27 17:58:12

为教堂垒球队编写统计网站。

我有一个SQL视图,它根据表格中的统计数据计算每场比赛的平均打击率。我使用该视图在MVC中构建了一个名为PlayerStats的模型。

我想创建数据并将其加载到如下模型中:

public class BattingAverage
{
    [Key]
    public int stat_id { get; set; }
    public int player_id { get; set; }
    public decimal batting_avg { get; set; }
    public decimal cumulative_batting_avg { get; set; }
}

在我的控制器中,我正在这样做:

var model = (from s in PlayerStats
            where s.season_id == sid && s.player_id == pid
            orderby s.game_no
            select g).AsEnumerable()
            .Select(b => new BattingAverage
            {
                stat_id = b.stat_id,
                player_id = b.player_id,
                batting_avg = b.batting_avg,
                cumulative_batting_avg = ***[[ WHAT TO DO HERE?? ]]***
            });

我不知道如何计算累积平均值以加载到我的模型中。最终目标是Json。对模型数据进行编码,以便在AmCharts中使用。

更新-我尝试过这个:

cumulative_batting_avg = getCumulativeAvg(sid, pid, b.game_no)

我的功能:

public decimal getCumulativeAvg(int season_id, int player_id, int game_no)
    {
        var averages = PlayerStats.Where(g => g.season_id == season_id && g.player_id == player_id && g.game_no <= game_no).ToArray();
        var hits = averages.Select(a => a.Hits).Sum();
        var atbats = averages.Select(a => a.AtBats).Sum();
        if (atbats == 0)
        {
            return 0.0m;    // m suffix for decimal type
        }
        else
        {
            return hits / atbats;
        }
    }

这在第一行返回了一个正确的平均值,但其余的都是零。当我在返回值上加上一个中断时,我看到命中率和atbats在函数内部正确地累积,但出于某种原因,avg没有添加到模型中。我做错了什么?

使用LINQ将累积平均值加载到MVC模型中

是的,基本上你想有一个子查询来获取所有游戏的平均值,我的理解正确吗?您可以使用LET关键字,这样当主查询在当前游戏的上下文中进行拉取时,LET子查询可以跨所有游戏进行拉取,如下所示:Simple Example subquery Linq

这可能会转化为:

from s in PlayerStats
let cs = context.PlayerStats.Where(i => i.PlayerID == s.PlayerID).Select(i => i.batting_avg).Average()
.
.
select new {
    batting_avg = b.batting_avg, /* for the current game */
    cumulative_batting_avg = cs
}

类似的东西,尽管我可能有点偏离语法。对于这种类型的方法,我经常担心LINQ子查询的性能(你永远不知道它会呈现什么),所以你可能想考虑使用存储过程(实际上取决于你有多少数据)

现在,从评论中,我想我明白了什么是累积打击率平均值。这听起来像是一场给定的比赛,它是基于那场比赛和前几场比赛的命中率和击球率总和的平均值。

假设你有一组已经被球员和赛季过滤过的统计数据:

var playerSeasonStats = PlayerStats.Where(g => 
    g.season_id == season_id && g.player_id == player_id && g.game_no <= game_no)
    .ToArray();

我最初写下一部分是作为林克的表达。但这只是一种习惯,在这种情况下,使用普通的for/each循环阅读要简单得多。

var playerSeasonStats = PlayerStats as PlayerStat[] ?? PlayerStats;
var averages = new List<BattingAverage>();
int cumulativeHits = 0;
int cumulativeAtBats = 0;
foreach (var stat in playerSeasonStats.OrderBy(stat => stat.game_no))
{
    cumulativeHits += stat.Hits;
    cumulativeAtBats += stat.AtBats;
    var average = new BattingAverage
    {
        player_id = stat.player_id,
        stat_id = stat.stat_id,
        batting_avg = stat.Hits/stat.AtBats,
        cumulative_batting_avg = cumulativeHits/cumulativeAtBats
    };
    averages.Add(average);
}