EF核心关系查询

本文关键字:查询 关系 核心 EF | 更新日期: 2023-09-27 18:02:11

我对实体框架相当陌生,我的表关系看起来有点像这样

public class Customer {
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}
public class Product {
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public Customer Customer { get; set; }
}

我想对Customer表进行查询,并且只包含最近创建的Product MAX(Id)

正常的SQL查询看起来像这样

SELECT * 
FROM Customer
INNER JOIN Product ON Customer.Id = Product.CustomerId
WHERE Product.Id = (SELECT MAX(Id) FROM Product WHERE CustomerId = Customers.Id)

我当前的EF查询是这样的,但是它返回所有的产品…

List<Customer> customers = _context.Customers
                .Include(c => c.Products)
                .ToList();

我尝试过这样的东西,这给了我正确的结果,但EF做了一堆查询,很快我就看到这似乎是错误的方式去它

List<Customer> customers = _context.Customers
                .Select(c => new Customer() {
                    Id = c.Id,
                    Name = c.Name,
                    c.Products = c.Products.Where(d => d.Id == c.Products.Max(max => max.Id)).ToList()
                }).ToList();

我想要一些建议,或者如果有不同的方法使这个工作

EF核心关系查询

看起来下面的查询可以用另一种方式写

SELECT * 
FROM Customer
INNER JOIN Product ON Customer.Id = Product.CustomerId
WHERE Product.Id = (SELECT MAX(Id) FROM Product WHERE CustomerId = Customers.Id)   

可以写成

SELECT TOP 1 *
FROM Customer
INNER JOIN Product ON Customer.Id = Product.CustomerId
Order by Product.Id desc

假设需要客户名,上述查询可以用LINQ编写,也可以使用EF编写,如下所示

var customers = _context.Customers.Join(_context.Products, cu => cu.id,
p => p.CustomerId, (cu,p) => new { cu,p})
.Select( c => new { prodId = c.p.Id,customername = c.cu.Name })
.OrderByDescending( c => c.prodId).Take(1);

如果你已经配置了导航属性1-n,我建议你使用:

var customers = _context.Customers
  .SelectMany(c => c.Products, (c, p) => new { c, p })
  .Select(b => new { prodId = b.p.Id, customername = b.c.Name })
  .OrderByDescending(c => c.prodId).Take(1);

对我来说更清晰,并且使用多个嵌套连接看起来更好。