0

我有一个包含以下实体的模型:

Game: Id
User: Id
UserRating: Id, UserId, GameId, Value

用户可以给游戏评分。

我想要一个查询,返回评分最高的前 5 场比赛。最高评分应以Value为基础,但当有2个或更多游戏具有相同评分时,还应考虑计数。

如何在查询中表达这一点,使用 lambda 表达式将结果列表作为游戏实体返回?

(使用 EF 4、MVC、SQL Server)。

4

1 回答 1

2

我假设“最高评分”是指“最高平均评分”?听起来你想要这样的东西:

var query = from rating in db.UserRating
            group rating by rating.GameId into ratings
            orderby ratings.Average(x => x.Value) descending,
                    ratings.Count() descending
            join game in db.Game on ratings.Key equals game.Id
            select game;

var top5Games = query.Take(5);

编辑:在非查询表达式形式中,这会更痛苦,但仍然可行:

var top5Games = db.UserRating
                  .GroupBy(rating => rating.GameId)
                  .OrderByDescending(ratings => ratings.Average(x => x.Value))
                  .ThenByDescending(ratings => ratings.Count())
                  .Join(db.Game, r => r.Key, g => g.Id, (r, g) => g)
                  .Take(5);

在这种情况下,在 lambda 语法中执行它并不算糟糕,因为您只是让游戏退出连接......但更一般地说,它变得更糟糕。这两种形式绝对值得理解和使用,这取决于手头查询的更简单方法。特别是,当您开始执行多个连接时,lambda 语法会变得很糟糕

请注意,这不会给出该游戏的评分...要获得该评分,您可能需要以下内容:

select new { Game = game,
             RatingAverage = ratings.Average(x => x.Value),
             RatingCount = ratings.Count() }

在查询结束时,而不仅仅是select game.

另请注意,您可能希望排除目前没有足够评分的游戏,否则游戏只有一个“完美”的评分将始终排在首位。

编辑:好的,在“游戏名称”的最后抢七局中,我肯定会使用查询表达式形式:

var query = from rating in db.UserRating
            join game in db.Game on ratings.Key equals game.Id
            select new { rating, game } into pair
            group pair by pair.game into pairs
            orderby pairs.Average(x => x.rating.Value) descending,
                    pairs.Count() descending,
                    pairs.Key.Name
            select pairs.Key;

var top5Games = query.Take(5);
于 2013-03-28T11:14:54.180 回答