LINQ を使用して、効率的な方法で DbContext をクエリするのに問題があります。データベースには、日付、名前、その他の情報を持つ 700,000 を超えるエンティティが含まれています。
私のコードでは、オブジェクトの新しいリスト (潜在的に 100,000 の要素を持つ可能性があります) が入ってきて、データベースにクエリを実行して、どの情報が新しいエンティティであるか、またはどの情報が更新が必要な既存のエンティティであるかを推測したいと考えています。
非常に効率的な方法で(可能であれば単一のクエリで)実行したいと思います。
これは私のコードです:
public class MyDbContext : DbContext
{
public DbSet<MyEntity> MyEntities { get; set; }
}
public class MyEntity
{
[Key]
public Guid Id { get; set; }
public DateTime Date { get; set; }
public string Name { get; set; }
public double Amount { get; set; }
public string Description { get; set; }
}
public class IncomingInfo
{
public DateTime Date { get; set; }
public string Name { get; set; }
public double Amount { get; set; }
}
public class Modifier
{
public void AddOrUpdate(IList<IncomingInfo> info)
{
using (var context = new MyDbContext())
{
//Find the new information
//to add as new entities
IEnumerable<MyEntity> EntitiesToAdd = ??
//Find the information
//to update in existing entities
IEnumerable<MyEntity> EntitiesToUpdate = ??
}
}
}
誰かがクエリの作成を手伝ってくれますか? どうもありがとうございました。
編集:申し訳ありませんが、2 つのエンティティが等しいと見なす方法を説明するのを忘れていました。Date プロパティと Name プロパティが同じ場合は、等しいです。
最初に LinqKit PredicateBuilder を使用して述語を作成しようとしましたが、あまり成功しませんでした (パラメーターが大きすぎるというエラーが発生し、複数のクエリを作成する必要があり、時間がかかりました)。
これまでのところ、私が見つけた最も成功した方法は、LEFT OUTER 結合を実装し、次の方法で実装した DbSet に受信リストを結合することでした。
var values = info.GroupJoin(context.MyEntities,
inf => inf.Name + inf.Date.ToString(),
ent => ent.Name + ent.Date.ToString(),
(inf, ents) => new { Info = inf, Entities = ents })
.SelectMany(i => i.Entities.DefaultIfEmpty(),
(i, ent) => new { i.Info.Name, i.Info.Amount, i.Info.Date, ToBeAdded = ent == null ? true : false });
IEnumerable<MyEntity> EntitiesToAdd = values.Where(i => i.ToBeAdded)
.Select(i => new MyEntity
{
Id = Guid.NewGuid(),
Amount = i.Amount,
Date = i.Date,
Name = i.Name,
Description = null
}).ToList();
私のテストには、データベースに 700,000 のエンティティが含まれています。着信情報リストには 70,000 項目が含まれています。ここで、50,000 は既存のエンティティで、20,000 は新しいエンティティです。このクエリの実行には約 15 秒かかりますが、これは私には正しくないようです。
うまくいけば、これで助けを求めるのに十分です。誰かがこれを手伝ってくれますか?どうもありがとうございました。