代码之家  ›  专栏  ›  技术社区  ›  chuckd

如何检查EF Core中是否存在当月创建的行(记录)

  •  1
  • chuckd  · 技术社区  · 1 年前

    我想知道是否有更有效的方法来检查我是否有在当月(2024年6月)创建的记录?

    目前我使用多种条件,但不知道是否有更有效的方法 DateTime ?

    var hasTransferFromCurrentMonth = await _dbContext.Transfers
      .Where(p => p.ReceiverId == transferDto.ReceiverId &&
        p.CreatedDate.Month == DateTime.UtcNow.Month &&
        p.CreatedDate.Year == DateTime.UtcNow.Year)
      .AnyAsync();
    1 回复  |  直到 1 年前
        1
  •  1
  •   Chris Schaller    1 年前

    作为最高效率LINQ到EF查询的一般规则,如果可能的话,应该避免在查询中进行计算或函数调用,并首先执行此逻辑。因此,对于日期范围,我们可以先计算边界日期,然后使用简单的介于逻辑之间的方法:

    DateTime currentMonthStart = DateTime.UtcNow.Date.AddDays(-DateTime.UtcNow.Day + 1);
    DateTime nextMonthStart = currentMonthStart.AddMonths(1);
    
    var hasTransferFromCurrentMonth = await _dbContext.Transfers
         .Where(p => p.ReceiverId == transferDto.ReceiverId 
                  && p.CreatedDate >= currentMonthStart 
                  && p.CreatedDate < nextMonthStart)
         .AnyAsync();
    

    这更有效,因为不需要对我们正在查询的数据进行转换,相反,RDBMS只需要与原始数据值进行比较。

    • 注:我使用过 少于 下个月,以覆盖最后一天的所有时间值。如果您的数据具有非零时间分量,并且您使用 小于或等于一个月的最后一天 那么它将排除出现在该月最后一天的任何记录。

    这里还有额外的好处,如果您在 CreatedDate 列,则RDBMS应该能够使用 索引查找 而不是更昂贵的扫描操作。


    这些规则也有例外,这是一般建议,为了优化LINQ to EF,通常最好检查生成的SQL,然后看看是否可以改进查询以生成更高效的SQL。

    不同的RDBMS还以不同的方式优化筛选条件中使用的日期查询和日期函数,但这将在不更改数据库模式的情况下产生最佳结果。