linq到实体的多个聚合(代码优先)

时间:2012-11-06 18:48:53

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

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

度过了糟糕的一天,无处可去。有人可以帮助我吗?

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(),                            
                        };

所以现在我只需要使用AveragePoints计算来考虑评论中提到的未在该时期内玩过的玩家。

1 个答案:

答案 0 :(得分:0)

我假设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()

            };