使用 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 = ??
}
}
}
有人可以帮我构建我的查询吗?非常感谢你。
编辑:对不起,我忘了解释我如何认为两个实体相等。如果 Date 和 Name 属性相同,则它们相等。
我首先尝试使用 LinqKit PredicateBuilder 构建谓词,但没有取得多大成功(遇到参数太大的错误,不得不进行多次查询,这需要时间)。
到目前为止,我发现的最成功的方法是实现 LEFT OUTER join 并将传入列表加入我以这种方式实现的 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 秒才能执行,这对我来说似乎不合适。
希望这足以寻求帮助。有人可以帮我一个吗?非常感谢你。