【问题标题】:Find duplicate objects that already exist in database查找数据库中已存在的重复对象
【发布时间】:2021-05-25 01:27:06
【问题描述】:

我有一个包含对象的数据库表。这些对象有一个 PK 和一个具有 4 个属性的唯一索引。我想要做的是将新对象添加到数据库中,并将重复的“旧”对象从另一个表移动到另一个表,即“历史”。

因此,当我上传新的 csv 文件时,我想获取数据库中所有与新 csv 文件中的对象重复的现有对象。

csv 文件可能很大并且有超过 10k 的对象,因此循环它们并检查数据库中是否存在索引/id 需要很长时间。

我尝试使用唯一索引键保存对象,但不知道如何获取已经存在的对象。

截图供参考:

Entity

Parent

【问题讨论】:

  • 你关心性能吗?或者只是通过纯 EF 需要它?
  • 我确实关心性能。我使用 ef,因为这是我唯一知道的。
  • 好吧,我将使用第三方 EF Core Extension 准备示例。您使用哪个数据库?
  • Azure Sql 服务器
  • 同时添加你的实体类。显示要做什么是最容易的。

标签: c# sql .net .net-core entity-framework-core


【解决方案1】:

由于 EF Core 出于性能原因不支持批量操作,因此最好使用第三方扩展(免责声明我是创建者之一)https://github.com/linq2db/linq2db.EntityFrameworkCore

为了快速阅读 CSV,我建议使用这个库 https://github.com/mgholam/fastCSV 它将通过 IEnumerable 连续加载文件,而不会占用大量内存。

最好用临时表实现这样的插入:

var items = ... // you have read CSV file and created enumeration of objects, let's name them SomeItem
using var db = ctx.CreateLinqToDBConnection();
using var temp = db.CreateTempTable("#to_inject", items);

var queryToHistory = 
   from s in db.GetTable<SomeItem>()
   from t in temp.InnerJoin(t => t.key1 == s.Key1 && t.Key2 == s.Key2 && t.Key3 == s.Key3)
   select s;

using var tran = db.BeginTransaction();

// inserting into History table
queryToHistory.Insert(db.GetTable<SomeItemHistory>(), s => new SomeItemHistory 
  {
     Key1 = s.Key1,
     Key2 = s.Key2,
     Key3 = s.Key3,
     
     Value1 = s.Value1,
     Value2 = s.Value2,
     ...
  });

// inserting new records or update existing
db.GetTable<SomeItem>()
  .Merge()
  .Using(temp)
  .OnTargetKey()
  .InsertWhenNotMatched()
  .UpdateWhenMatched()
  .Merge();

tran.Commit();

【讨论】:

  • 这很好用!但是在创建“CreateTempTable”时。它说 Id 必须是数字。有没有办法改变这个?
  • 嗯,哪个实体?数据库中的Id 是哪种类型?
  • 使用表格的类和 DDL 更好地更新您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 2018-08-13
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 2011-10-07
相关资源
最近更新 更多