【问题标题】:How to convert this SQL query into LINQ in c#如何在 C# 中将此 SQL 查询转换为 LINQ
【发布时间】:2020-10-10 12:28:31
【问题描述】:
UPDATE  m
SET     m.Score = s.AScore + '-' + s.BScore
FROM    #Matches m
        INNER JOIN Scores s ON m.MatchId = s.MatchId 
        AND s.InfoTypeId = (
                             CASE 
                              WHEN m.SportId = 1 AND (m.StatusId >= 13 AND m.StatusId <= 17) THEN 10
                              WHEN m.SportId = 1 AND m.StatusId = 20 THEN 24
                              WHEN m.SportId = 1 AND m.StatusId = 21 THEN 23
                              WHEN m.SportId = 1 AND m.StatusId = 18 THEN 8
                              ELSE 5
                             END
                           )

我在 C# 中有两个列表,一个是 Matches,第二个是 Scores,我想从这些列表中获取结果,就像这个查询将返回的结果一样。表示我想更新“匹配”列表的“分数”属性,就像它在 SQL 查询中更新一样。
请提供任何帮助。


Matches.ForEach(m => m.Score = (Scores.Where(ms => ms.MatchId == m.MatchId
                                                   && ms.ScoreInfoTypeId == ((m.SportId == 1 && m.StatusId >= 13 && m.StatusId <= 17) ? 10
                                                                              : (m.SportId == 1 && m.StatusId == 20) ? 24
                                                                              : (m.SportId == 1 && m.StatusId == 21) ? 23
                                                                              : (m.SportId == 1 && m.StatusId == 18) ? 8
                                                                              : 5)).Select(ms => ms.AScore + "-" + ms.BScore).FirstOrDefault()));

我试过了,但我觉得它太贵了。这需要太多时间。请问有什么优化的方法吗?

【问题讨论】:

  • 您使用哪种 ORM? EF 6、EF Core、LInq2db,还有什么?
  • 我不清楚,你想实现什么。1)你只是想以某种方式生成完全相同的 Sql,2)你想制作自动计算属性 3)你想设计一个解决方案,这也是一样的,但在 c# 4) 中还有别的吗?
  • 使用 linq2db 很容易。但 EF 查询可能取决于匹配的大小 - 或者根本不可能。
  • @AlexanderPetrov,我正在开发 .net Core。我没有使用EF。我已经使用 Dapper 获得了列表。我正在尝试使用 LINQ 或 lambda 表达式来实现这个概念。请问你能做到吗。如果您需要有关此查询的更多信息,请告诉我,我会提供。谢谢。

标签: c# linq lambda


【解决方案1】:

在 LinqPad 中试试这个例子。您可以使用查询语法加入 2 个列表并迭代结果以设置匹配分数。我用字典来简化那个 switch case。

void Main()
{
    var matches = new[]{
    new Match{MatchId=1,SportId=1,StatusId=13,Score=""},
    new Match{MatchId=2,SportId=1,StatusId=18,Score=""},
    new Match{MatchId=3,SportId=2,StatusId=24,Score=""},
    };
    var scores = new[]{
     new{MatchId=1,AScore="10",BScore="0",InfoTypeId=10},
     new{MatchId=2,AScore="20",BScore="0",InfoTypeId=8},
     new{MatchId=3,AScore="30",BScore="0",InfoTypeId=5},
    };
    
    var dict = new Dictionary<int,int>{[13]=10,[14]=10,[15]=10,[16]=10,[17]=10,[20]=24,[21]=23,[18]=8};
    var data = (from m in matches 
               join s in scores on m.MatchId equals s.MatchId 
               where s.InfoTypeId == ((m.SportId == 1 && dict.ContainsKey(m.StatusId))? dict[m.StatusId] : 5)
               select new {m,s}
               ).ToList();
    data.ForEach(o => 
    { 
        o.m.Score = o.s.AScore + "-" + o.s.BScore;
    });
    matches.Dump();
}

class Match{public int MatchId; public int SportId; public int StatusId; public string Score;}

【讨论】:

  • 您好 Gokul,感谢您的帮助。让我试试这个解决方案。我希望它会奏效。谢谢。
  • 干杯,伙计!您可以探索docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… 来学习 LINQ。此外,LinqPad 工具是实验和学习的绝佳场所。他们有很多来自实际书籍的 LINQ 示例,您可以下载和玩来学习。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2016-01-23
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多