【问题标题】:The problem with translation of a SQL-query to Entity Framework将 SQL 查询转换为实体框架的问题
【发布时间】:2021-05-26 11:22:41
【问题描述】:

有Product表和Price表,价格表包含Product表的外键Price.ProductId。 Price 表包含有关每个产品的价格信息,这些价格可能会根据 StartDate 进行更改,换句话说,用户可以为任何产品指定确切的 StartDate 的新价格。 它如何在实体框架的帮助下实现? 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.Price,只有一个实际价格必须与 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" 
)

【问题讨论】:

  • 只有一个实际价格必须与产品相关联 - 您的意思是对于您想要获得当前价格的任何产品?也许您应该有一个当前价格为 null 的 PriceEnd 列,然后放置一个 CurrentPrice 的属性,该属性使用 priceend == null 谓词执行 Single 或 First。查询比每次对每个产品的每个价格进行分组要快

标签: c# postgresql entity-framework-6 asp.net-core-5.0


【解决方案1】:

大概是这样吧——

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();

【讨论】:

    【解决方案2】:

    如果没有@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) ;
    

    很遗憾,我将不得不将翻译保留为您的晦涩语言(实体框架),因为我不知道。无论如何,希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多