比较内存列表与数据库列表的有效方法

问题描述 投票:0回答:1

使用 .NET 6 和实体框架,我正在尝试一种基于组合键的有效方法来查找和标记数据库中记录之间的差异。考虑这个类具有由 ID 和 Year 组成的复合主键。

class Building
{
    public int ID { get; set; }
    public int Year { get; set; }
    public string Name { get; set; }
    public double Size { get; set; }
    public decimal LastSalePrice { get; set; }
}

我在内存中检索年份 == 2022 的所有建筑物。现在我需要比较并标记列表中所有建筑物与年份为 2021 的建筑物之间的差异。

我的看法有两种:

  1. 需要另一个类来保存标志(这可能不是最好的方法,因为建筑列表和更改标志都需要发送到前端,这将需要一个额外的类来将所有信息放在一起)
  2. 通过添加“NameChanged”、“SizeChanged”、“LastSalePriceChanged”布尔值来标记差异来修改构建类

我的目标是避免检索 2021 年的建筑物列表,然后在内存中进行逐项比较。相反,我正在寻找一种在数据库级别运行的解决方案,以清晰地标记差异。例如,如果建筑物在 2022 年存在但在 2021 年不存在,则所有标志应设置为“true”。

我对在性能和资源使用方面最有效的方法感兴趣,并避免不必要的数据检索。

谢谢!

PS:我尝试检索“2021”年的建筑物列表并比较每个建筑物 ID,但它非常冗长并且是“面向业务逻辑”的解决方案。这不是我想要的“干净的、面向数据层的”解决方案。

entity-framework linq optimization architecture comparison
1个回答
0
投票

如果每年的 ID 相同,并且复合唯一键是 ID 和年份的组合,那么您可以使用自连接:

var differingBuildings = await context.Buildings
    .Join(context.Buildings, b1 => b1.Id, b2 => b2.Id,
         (b1, b2) => new { BuildingYear1 = b1, BuildingYear2 = b2 })
    .Where(x => x.BuildingYear1.Year = year1 
        && x.BuildingYear2.Year = year2
        && (x.BuildingYear1.Name != x.BuildingYear2.Name
            || x.BuildingYear1.Size != x.BuildingYear2.Size
            || x.BuildingYear1.LastSalePrice != x.BuildingYear2.LastSalePrice))
    .Select(x => new 
    {
        x.BuildingYear2.Id,
        x.BuildingYear2.Year,
        NameChanged = x.BuildingYear1.Name != x.BuildingYear2.Name,
        SizeChanged = x.BuildingYear1.Size != x.BuildingYear2.Size,
        LastSalePriceChanged = x.BuildingYear1.LastSalePrice != x.BuildingYear2.LastSalePrice
    }).ToListAsync();

这将返回两年内名称、大小或销售价格不同的任何建筑物,以及最近(假设第 2 年 > 第 1 年)年份和值发生变化的标志。这可能不会是一个特别高效的查询,因此根据数据量,简单地将两年内的所有建筑物(或基于 ID 的建筑物集)加载到内存中并进行比较可能会更有效在那里。

© www.soinside.com 2019 - 2024. All rights reserved.