【问题标题】:Top Highscore LINQ to SQL最高分 LINQ to SQL
【发布时间】:2012-01-03 14:12:59
【问题描述】:

我有一张名为“HighScore”的在线高分表。此表包含以下列:

Id,int(自动值) 名称,字符串(玩家姓名) Guid,字符串(玩家 ID) 分数,int(分数) Coins, int (玩家的硬币) 创建,datetime(创建日期)

我需要的是前 50 个分数,但按 Guid 分组。我发现了一个几乎可以工作的 LINQ 表达式。 How do I get the MAX row with a GROUP BY in LINQ query?

最后我需要一个我的 HighScore 对象的列表。通过上面的表达式,我得到了一个匿名列表。

编辑: 实际上我的表的名称是“CatGameScore”,但我在这篇文章中更改了它。

表格内容(仅说明了指南和日期)

Id     Name     Guid     Score     Coins     Created
1      Hugo     123-123  150       10        <date>
2      Peter    456-456  600       19        <date>
3      Hugo     123-123  550       26        <date>

我的输出应该是这样的:

Id     Name     Guid     Score     Coins     Created
2      Peter    456-456  600       19        <date>
3      Hugo     123-123  550       26        <date>

输出必须是一个列表。我可以获得每人前 50 名的分数,但我无法创建我的分数对象列表。

感谢任何提示。

安迪

【问题讨论】:

  • 您能否用(比如说)4 行、重复 1 个 guid 和(比如说)2 个其他 guid 来说明,这样我们就可以准确地看到您想要的输出?
  • 如果每个玩家有多个分数,为什么表格称为HighScore。也许该表应该简单地称为Score

标签: c# sql linq


【解决方案1】:

除此之外:How do I get the MAX row with a GROUP BY in LINQ query?

您需要使用TakeSkip 方法来帮助您完成任务。

类似

MyScoreCollection.OrderByDescending(x => x.Score).Take(50) .GroupBy(x => x.Guid); 

【讨论】:

  • 我在第一篇文章中添加了一些 cmets。我需要一个我的 Score 对象的列表。谢谢
【解决方案2】:

这样的?

context.HighScoreSet.OrderByDescending(x => x.Score)
                    .Take(50)
                    .GroupBy(x => x.Guid);

【讨论】:

    【解决方案3】:

    好的,这样的事情可以解决问题

    //assuming you have a List<HighScore>
    var scores = new List<HighScore>();
    

    编辑: 从数据库中获取所有分数(点击 db 一次)。然后,您可以使用 Tuple 对象而无需任何 SQL 转换

    scores = (from s in context.ScoreSet //or something like this
             select s).ToList();
    

    结束编辑

    //get list of Tuples containing player Id and max score
    var topScores = from s in scores
                    group s.Score by s.Guid into grouping
                    orderby grouping.Max() descending
                    select new Tuple<string, int>(grouping.Key, grouping.Max()).Take(50);
    
    //get matching HighScore records from List<HighScore>
    var scoreRecords = from score in scores
                       let tuple = new Tuple<string, int>(score.Guid, score.Score)
                       where topScores.Contains(tuple)
                       select score;
    

    【讨论】:

    • 这段代码对我来说看起来不错。我得到了 topScores 但我无法从我的“分数”列表中得到匹配的 HighScore 记录。我收到以下错误消息:成员 'System.Tuple`2[System.String,System.Int32].Item1' 没有支持的 SQL 转换。
    • @Andy :很抱歉现在才回到这个问题,过去几周我一直不在我的电脑前。看起来您正在使用 LINQ-to-SQL 实现,对吗?如果是这种情况,那么是的,没有将 Tuple 对象明显转换为 SQL。一种可能的解决方法是在开始过滤高分等之前从表中获取所有内容。我将发布对我的答案的编辑以进行说明。
    【解决方案4】:

    这是我的答案,我将HighScore 表称为Scores,因为这对我来说似乎更正确。

    var highScorePerPlayer =
        scores.GroupBy(
            s => s.Guid,
            s => s.Score,
            (playerID, scores) => 
                new KeyValuePair<string,int> (playerID, scores.Max()));
    
    var top50HighScores = highScorePerPlayer.OrderByDescending(hs => hs.Value)
        .Take(50);
    

    通过阅读问题,我认为您希望每个玩家都获得明显的高分,因此每个玩家只会在列表中出现一次。如果不是这种情况,您应该像其他答案一样反转操作。结果将是IEnumerable&lt;KeyValuePair&lt;string, int&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多