将 SQL 查询转换为实体框架的问题

问题描述

有Product表和Price表,price表包含Product表的外键Price.ProductId。 价格表包含有关每个产品价格的信息,这些价格可能会根据开始日期更改,换句话说,用户可以为任何产品指定确切开始日期的新价格。 如何在实体框架的帮助下实现? Product 实体模型有一个包含来自 Price 表的实体的集合,但提取如此多的 Price 实体并不合适,因为 Product 在最终查询中必须仅与实际价格相关联。

有 2 个模型可以映射表格 -

public partial class Product
{
    public long Id { get; set; }
    public string ProductName { get; set; }
    public virtual ICollection<Price> Prices { get; set; }
}

public partial class Price
{
    public long Id { get; set; }
    public long ProductId { get; set; }
    public DateTime StartDate { get; set; }

    public virtual Product Product { get; set; }
}

不可能提取完整的集合 Product.Prices,只有一个实际价格必须与 Product 相关联。 看起来下面的 sql 查询可以提取数据,但如何在 EF 的帮助下完成?

select public.price.,public.product. from public.product  
inner join public.price on public.price."ProductId" = public.product."Id"
where public.price."Id" in 
(
    select max(public.price."Id") from public.price
    where public.price."StartDate" <= current_date 
    group by  public.price."ProductId" 
)

解决方法

可能,它必须是类似的 -

var productsWithPrice = await db.Product
                        .Select(p => new 
                        { 
                            Product = p,Price = p.Prices.Where(x => x.StartDate <= DateTime.UtcNow).OrderBy(x => x.StartDate).LastOrDefault()
                        })
                        .ToListAsync();
,

如果没有@CaiusJard 提到的价格终止列 (PriceEnd),我们必须假定当前价格是具有最新开始日期的价格。您可以使用 Not Exists 谓词获得此信息,其中产品价格没有更大的开始日期。这可以从价格表中严格检索。然后将结果加入到 Products 表中。在直接 SQL 中变成:

select prd.id,prd.productName,curr_pri.price
  from products prd
  join  (select productId,price
           from prices pri2
          where not exists (select null 
                              from prices pri3
                             where pri3.ProductId = pri2.ProductId  
                               and pri3.StartDate > pri2.StartDate
                           )  
       ) curr_pri
      on (prd.id = curr_pri.productId) ;

不幸的是,我将不得不翻译成你的模糊语言(实体框架),因为我不知道。无论如何,希望这会有所帮助。