【问题标题】:Strange results using dates in linq queries using EF Core使用 EF Core 在 linq 查询中使用日期的奇怪结果
【发布时间】:2017-04-05 16:09:20
【问题描述】:

尝试使用 Linq 和 EF Core 对日期列进行简单查询时,我得到了奇怪的结果。

如果我使用 DateTime 列表中的日期运行查询,我不会得到任何结果。如果我替换 DateTime.Now 并添加负天数,以便如果匹配 DateTimes 列表中的日期,则查询将按预期返回结果。

那么 DateTime.Now 和另一个 DateTime 对象有什么区别呢?

在实践中,为什么会这样(在第一个示例中现在倒带 30 天给出与第二个示例中的 datesToCheck[0] 相同的日期):

 var reports = from r 
               in db.DailyReports
                    .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                             && r.Date > DateTime.Now.AddDays(-30)) 
               select r;

但不是这个:

var reports = from r 
              in db.DailyReports
                   .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                            && r.Date > datesToCheck[0]) 
              select r;

数据库是 SQL Server 2017,列是不可为空的 smalldatetime

datesToCheck 列表是这样生成的:

var datesToCheck = new List<DateTime>();

var startDate =  DateTime.Now;
//get Monday date three weeks ago
if (DateTime.Now.DayOfWeek != DayOfWeek.Monday)
{
    while (startDate.DayOfWeek != DayOfWeek.Monday)
        {
            startDate = startDate.AddDays(-1);
        }
}

startDate = startDate.AddDays(-21);
while (startDate < DateTime.Now)
{
    if (startDate.DayOfWeek != DayOfWeek.Saturday || startDate.DayOfWeek != DayOfWeek.Sunday)
    {
        datesToCheck.Add(startDate);
        startDate = startDate.AddDays(1);
    }       
}   

【问题讨论】:

  • 没有意义,你能告诉我们datesToCheck[0] 声明和值吗?
  • 没问题 Juan Carlos - 我已将其添加到问题中
  • 没有意义,两个谓词都将在内存中进行评估(首先是因为AddDays 函数,其次是因为数组/列表索引器)。只要datesToCheck[0] 包含DateTime.Now.AddDays(-30),两个查询都应该返回一个相同的结果。

标签: sql-server entity-framework linq datetime asp.net-core


【解决方案1】:

EF6 以及据我所知所有版本的 EF 中都存在相同的行为。基本上,编译器不够聪明,无法决定是否应评估 datesToCheck[0] 或将其转换为 SQL。如果您将值存储在变量中,然后在 LINQ 查询中使用该变量,则该查询将起作用。另见:Why can't we use arrays in Entity Framework queries?

【讨论】:

    【解决方案2】:

    您可能有一些数据类型问题,试试:

    DateTime datesToCheck = DateTime.Now.AddDays(-30);
    var reports = from r 
                  in db.DailyReports
                       .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                                && r.Date > datesToCheck ) 
                  select r;
    

    【讨论】:

    • 感谢 Juan Carlos - 这与将 DateTime.Now.AddDays(-30) 放在查询中一样。只有当我尝试使用 DateTime 列表中的值时它才会失败。即使我创建了一个新的 DateTime 变量并将列表中的值分配给它,它仍然不返回任何结果。
    • 正如我所说,问题出在datesToCheck[0] 变量上,您是否调试了该值?我仍在检查您的代码,但还没有看到任何内容。
    猜你喜欢
    • 2017-01-18
    • 2020-05-11
    • 2023-04-02
    • 1970-01-01
    • 2014-07-05
    • 2021-05-03
    • 2019-12-17
    • 2021-02-22
    • 1970-01-01
    相关资源
    最近更新 更多