【问题标题】:Most efficient way to check for existence of multiple items检查多个项目是否存在的最有效方法
【发布时间】:2016-05-27 16:08:30
【问题描述】:

有谁知道最有效的方法是检查大型数据库表中是否存在多个项目(最多 1000 个)(1,000,000 行+),看看是否需要添加它们,使用 EF / Linq / Sql Server db(托管在 Azure 上)?

目前,使用以下两种方法,我的性能一直很慢(尽管当我最初在本地 Sql 数据库上开发时,它要好得多)。

我是否需要考虑离开 EF 来完成这项任务,并直接针对 db 运行一些 SQL?

//loop to check all imported items against db
private void ImportNewSerialsWorkerUsingLoopCheck(List<foo> importedFoos)
{
    List<foos> foosToAddToDb = new List<foo>();
    foreach (var foo in importedFoos)
    {
        fooCheck = context.Foos.FirstOrDefault(f => f.Serial == foo.Serial);
        if (fooCheck == null)
        {
            foosToAddToDb.Add(foo);
        }
    }
    context.foos.AddRange(foosToAddToDb);
}


//use Any() to check all imported items against db
private void ImportNewSerialsWorkerUsingAnyCheck(List<foo> importedFoos)
{
    var foosToAddToDb = importedFoos.Where(i => !context.foos.Any(f => f.Serial == i.Serial)).ToList();    
    context.foos.AddRange(foosToAddToDb);
}

更新

我刚刚在 var foosToAddToDb = importedFoos.Where(i =&gt; !context.foos.Any(f =&gt; f.Serial == i.Serial)).ToList(); 命令中使用 .Any() LINQ 命令对本地 sql db 运行 sql profiler 跟踪,并发现 EF 将其作为 importedFoos 中每个项目的单独 sql 查询运行,所以使用这种方法肯定没有任何优势。

【问题讨论】:

    标签: c# entity-framework linq-to-sql azure-sql-database


    【解决方案1】:

    您的第二个 sn-p 正在执行 EF 查询,作为 Linq to objects 查询的一部分,因此它对每个项目执行查询。您只需执行一次 EF 查询即可往返数据库。

    var serials = importedFoos. Select(foo => too.Serial);
    var existing = context.Foos.Where(foo  => serials.Contains(foo.Serial));
    var toAdd = importedFoos.Except(existing);
    

    【讨论】:

    • 啊,谢谢 Servy,我会尽快尝试的,我过去曾犯过不必要的 .ToList() 调用。
    • @Ted 如果importedFoos 实际上是您不必要地具体化的 EF 查询,那么这要容易得多。只是不要实现它并写 context.Foos.Except(importedFoos); 就完成了,并且也是最有效的实现。
    猜你喜欢
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 2023-03-22
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多