代码之家  ›  专栏  ›  技术社区  ›  Erik Funkenbusch

如何从Linq2Sql查询生成更好的SQL

  •  2
  • Erik Funkenbusch  · 技术社区  · 14 年前

    我有以下疑问:

    var data = from d in dc.GAMEs 
        where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now select d; 
    

    这将生成一些看起来很奇怪的SQL,如下所示:

    SELECT {...} WHERE DATEADD(ms, ((CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 10000) % 86400000, CONVERT(DateTime,DATEADD(day, (CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 864000000000, [t0].[GAMEDATE]))) >= @p0
    

    为什么会有这么多SQL?有没有更好的办法来处理呢?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Mark Byers    14 年前

    如果您可以更改模式,那么处理它的最佳方法就是使用单个 datetime2 列而不是单独的 date time 领域。当前查询将无法使用索引。

    否则,您可以尝试按以下方式重写查询:

    DateTime now = DateTime.Now;
    var data = from d in dc.GAMEs 
        where (d.GAMEDATE > now.Date) ||
              (d.GAMEDATE == now.Date && d.GAMETIME.Value.TimeOfDay >= now.TimeOfDay)
        select d; 
    

        2
  •  0
  •   Amy B    14 年前

    作为替代(因为最外层或是索引的祸根)

    DateTime now = DateTime.Now;
    DateTime today = now.Date;
    TimeSpan timeOfDay = now.TimeOfDay;
    
    var data =
      from d in dc.GAMEs  
      where d.GAMEDATE >= today
        && (d.GAMEDATE > today || d.GAMETIME.Value.TimeOfDay >= timeOfDay) 
      select d;