【发布时间】:2013-07-10 15:50:13
【问题描述】:
使用 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 秒,这对我来说似乎不合适。
希望这足以寻求帮助。有人可以帮我一个吗? 非常感谢。
【问题讨论】:
-
你能告诉我们你已经尝试过什么吗?
-
是否通过
Guid Id属性知道两个实体是否应该被视为相同? -
哇,人们的速度太快了,不能直接关闭和关闭 - 正在回复中,希望能回答这个问题。现在,甚至无法开始与用户的对话(至少通过答案,将不得不离开现场):-/ 希望有一个选项来对保留提出异议。
-
这是我的回答:pastebin.com/pVv6bACW 基本总结,在 100,000 次潜在更新中,您将遇到 EF 的限制,并且必须做一些额外的工作来保持速度。
-
我用我目前发现的内容和我的问题编辑了我的问题。希望这是一个足够的问题。
标签: c# linq entity-framework