c# - EF core 2.1 中具有 lambda 表达式的最大 n 个组

标签 c# sql-server entity-framework-core

我正在尝试编写一个 lambda 查询来检索所有可供出租或即将推出的产品(其中结束日期为 10 天后)。该查询将返回所有以前从未租用过的产品或已租用但即将可用的产品。

   public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Rent> Rents { get; set; }
}

public class Rent
    {
        public int Id { get; set; }
        public Product Product { get; set; }
        public int ProductId { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public DateTime CreationTime { get; set; }
    }

通常 SQL 查询如下:

SELECT p.*, r1.*
FROM Products p
LEft JOIN Rents r1 ON (p.id = r1.ProductId)
LEFT OUTER JOIN Rents r2 ON (p.id = r2.ProductId AND 
    (r1.CreationTime < r2.CreationTime OR r1.CreationTime = r2.CreationTime AND r1.id < r2.id))
WHERE r2.id IS NULL AND (r1.EndDate is NULL OR r1.EndDate<='2018-06-24'); 

最佳答案

通常你会使用这样的东西:

from p in db.Products
let r = p.Rents.OrderByDescending(r => r.CreationTime).FirstOrDefault()
where r == null || r.EndDate <= DateTime.Now.Date.AddDays(10)
select new { p, r }

不幸的是,即使在目前最新的 EF Core 2.1 中,这也会导致 N + 1 次查询。

因此,您可以使用 SQL 查询的 LINQ 等效项。您应该使用 SQL NOT EXISTS 构造的 LINQ 等效项(即 !Any)来代替第二个反连接:

from p in db.Products
from r in p.Rents.DefaultIfEmpty()
where r == null || (r.EndDate <= DateTime.Now.Date.AddDays(10) &&
    !p.Rents.Any(r2 => r.CreationTime < r2.CreationTime || (r.CreationTime == r2.CreationTime && r.Id < r2.Id)))
select new { p, r }

这很好地转换为单个 SQL 查询。

关于c# - EF core 2.1 中具有 lambda 表达式的最大 n 个组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50858204/

相关文章:

c# - 在 WPF .NET Framework 中使用自定义任务管理器时,如何防止进程重复?

sql-server - 使用 cfqueryparam 创建准备好的语句的条件?

entity-framework-core - 我在使用 Entity Framework Core 2.0 在 SQL Server Express 中创建数据库时遇到问题

c# - IOAuthCredentials 哪个命名空间包含这个

c# - 在 WPF 中构建 CAD 程序

sql-server - T-SQL 获取所有唯一组及其使用计数

javascript - Sequelize 不会从数据库获取表

c# - EF核心: conditional query inside Include method

c# - 如何使用 Entity Framework Core 在 LINQ 更新语句中使用 CURRENT_TIMESTAMP?

c# - ASP.NET Web 应用程序在部署后不会卸载 AppDomains