【问题标题】:I have a SQL query and I want to convert it to linq我有一个 SQL 查询,我想将其转换为 linq
【发布时间】:2021-12-29 19:26:00
【问题描述】:

我有一个要转换为 Linq 的 SQL 查询。

这是我的 SQL 查询:

SELECT
    Calisanlar.CalisanId,
    CovidYakalanmaTarih, 
    CovidBitisTarih 
FROM
    Calisanlar 
INNER JOIN 
    Covids ON Calisanlar.CalisanId = Covids.CalisanId 
WHERE
    Calisanlar.CalisanId IN (SELECT TOP 10 CalisanId  
                             FROM Hastaliklar 
                             GROUP BY CalisanId 
                             ORDER BY COUNT(*) DESC)
    AND DATEDIFF(DAY, CovidYakalanmaTarih, GETDATE()) BETWEEN 0 AND 30 

我编写了这段 C# 代码,但它没有按预期工作,因为我没有编写“DATEDIFF(DAY, CovidYakalanmaTarih, GETDATE()) BETWEEN 0 AND 30”linq 版本:

var query = context.Hastaliklar
                   .GroupBy(x => x.CalisanId)
                   .OrderByDescending(grp => grp.Count())
                   .Select(grp => grp.Key)
                   .Take(10)
                   .ToList();

var result = from hastalik in context.Hastaliklar
             join covid in context.Covids
                  on hastalik.CalisanId equals covid.CalisanId
             where query.Contains(hastalik.CalisanId) 
                   && EF.Functions.DateDiffDay(covid.CovidYakalanmaTarih, covid.CovidBitisTarih)
             select new SonBirAyCovidDto
                        {
                            CalisanId = covid.CalisanId,
                            CovidYakalanmaTarih = covid.CovidYakalanmaTarih,
                            CovidBitisTarih = covid.CovidBitisTarih
                        };

【问题讨论】:

  • 在哪些方面没有按预期工作?
  • EF.Functions.DateDiffDay 模拟您的 DATEDIFF,但您的 LINQ 中没有任何内容可以模拟 BETWEEN 0 AND 30
  • 是的,反正我写不出它的 linq 版本
  • 我没有写“DATEDIFF(DAY, CovidYakalanmaTarih, GETDATE()) BETWEEN 0 AND 30” linq 版本@StriplingWarrior
  • 假设您不需要 BETWEEN 的某个水晶球的未来数据。 >= 30 就够了。

标签: sql entity-framework linq linq-to-sql


【解决方案1】:

EF Core 中没有直接转换为 BETWEEN,但可以设置其他条件。此外,最好从第一个查询中删除 ToList(),在这种情况下,您将只有一次到数据库的往返。

var query = context.Hastaliklar
    .GroupBy(x => x.CalisanId)
    .OrderByDescending(grp => grp.Count())
    .Select(grp => grp.Key)
    .Take(10);

var result = 
    from hastalik in context.Hastaliklar
    join covid in context.Covids
        on hastalik.CalisanId equals covid.CalisanId
    where query.Contains(hastalik.CalisanId) 
        && covid.CovidYakalanmaTarih <= covid.CovidBitisTarih
        && EF.Functions.DateDiffDay(covid.CovidYakalanmaTarih, covid.CovidBitisTarih) <= 30
    select new SonBirAyCovidDto
    {
        CalisanId = covid.CalisanId,
        CovidYakalanmaTarih = covid.CovidYakalanmaTarih,
        CovidBitisTarih = covid.CovidBitisTarih
    };

【讨论】:

  • “不得不”可能有点强。使用 ToList() ,它将在一次往返中具体化十个项目的列表,然后将它们作为WHERE IN (...) 子句插入第二个查询中。所以它可能仍然可以与 ToList() 一起使用,但将整个事情放在一次往返中可能是个好主意,就像你建议的那样。
  • @StriplingWarrior,说得好,已更正。
猜你喜欢
  • 2015-06-08
  • 2021-01-19
  • 2021-11-29
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2021-02-15
相关资源
最近更新 更多