【问题标题】:Multiple aggregates in linq to entities (code first)linq 中的多个聚合到实体(代码优先)
【发布时间】:2012-11-09 05:36:04
【问题描述】:

给定以下模型,我希望能够检索单个玩家获得的积分数以及给定时间段内所有玩家获得的平均积分数。这应该在单个数据库查询中完成(我还想要其他统计数据,例如每个团队的平均得分,稍后会出现,但概念应该是相同的)。

度过了糟糕的一天,却一无所获。有人可以帮帮我吗?

public class Player
{
    public int Id { get; set; }
    public ICollection<PlayerGame> PlayerGames { get; set; }

    ...
}

public class PlayerGame
{
    public int Id { get; set; }

    public int Points { get; set; }

    public int PlayerId { get; set; }
    public Player Player { get; set; }

    public int GameId { get; set; }
    public Game Game { get; set; }

    ...
}

public class Game
{
    public int Id { get; set; }

    ...
}

编辑:

好的。暂时将游戏实体排除在外,并更改您的代码以适应我的回购。这就是我现在拥有的:

var query = from p in _playerRepository.Query()
                        from pg in p.PlayerGames
                        group new { p, pg } by 1 into ppg
                        select new
                        {
                            SinglePlayerPointsGained = (from x in ppg
                                                        where x.p.Id == playerId && x.pg.Date > startDateTime
                                                        select x.pg.Points).Sum(),
                            AveragePoints = (from x in ppg 
                                             where x.pg.Date > startDateTime
                                             select x.pg.Points).Average(),                            
                        };

所以现在我只需要平均点数计算来考虑评论中提到的在此期间未参加比赛的球员。

【问题讨论】:

  • 您是否找到了解决方案或在建议的答案中遇到了问题?
  • 谢谢。还在玩它。直接使用存储库而不是上下文,因此对其进行了轻微调整(没有显式连接 - 只是多个 from 语句)并且它返回数据正常。唯一的问题是,仅计算在此期间玩游戏的人的平均值,而我需要所有玩家的平均值,无论他们是否在此期间玩游戏。假设这意味着不使用 Average() 并根据期间/总玩家的总积分手动计算,但尚未使用单个语句进行此工作。有什么想法吗?
  • 您只需将datetime where 语句移动到SinglePlayerPointsGained 部分。我更新了我的答案 - 这就是你要找的吗?此外,如果您使用所做的修改更新您的问题,这可能会有所帮助
  • AveragePoints 仍然需要考虑日期,但我想将所有未参加比赛的球员包括在平均计算中。例如玩家 1 得分 4,玩家 2 得分 5,玩家 3 在此期间不上场。我希望平均值为 9/3 = 3 而不是 9/2 = 4.5。将用我所做的更改更新我的问题。谢谢。

标签: entity-framework entity-framework-4 linq-to-entities


【解决方案1】:

我假设 Game 类有一个 DateTime 属性。基本思想是使用group by 1 技巧

DateTime startDateTime, endDateTime;

int playerId;

var query = from p in context.Players
            join pg in context.Players on p.Id equals pg.PlayerId
            join g in context.Games on pg.GameId equals g.Id               
            group new { p, pg, g } by 1 into ppgg
            select new {
               SinglePlayerPointsGained = (from x in ppgg
                                           where x.p.PlayerId == playerId
                                           where x.g.DateTime >= startDateTime && x.g.DateTime <= endDateTime
                                           select x.pg.Points ).Sum(),
               AveragePoints = (from x in ppgg
                                group x.pg.Points by x.p.PlayerId into g
                                select g.Key).Average()

            };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多