为教堂垒球队写一个统计网站。
我有一个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.Encode模型数据,以便在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;
}
}
这在第一行中返回了正确的平均值,但其余时间为零。当我在返回时休息时,我看到命中和响应在函数内正确累积,但由于某种原因,avg没有被添加到模型中。我做错了什么?
答案 0 :(得分:0)
是的,基本上你想要一个子查询来拉平所有游戏的平均值,我的理解是否正确?你可以使用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子查询的性能(你永远不知道它将要呈现什么),所以你可能想要考虑使用存储过程(实际上取决于你有多少数据)< / p>
答案 1 :(得分:0)
现在从评论中我想我明白累积击球率是多少。这听起来像是给定的游戏,它是基于该游戏和之前游戏中的点击和击球总和的平均值。
所以,让我们说你有一系列已被玩家和季节过滤的统计数据:
var playerSeasonStats = PlayerStats.Where(g =>
g.season_id == season_id && g.player_id == player_id && g.game_no <= game_no)
.ToArray();
我最初将下一部分写成Linq表达式。但这只是一种习惯,在这种情况下,使用正常的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);
}