2016-05-27 6 views
3

大きなデータベーステーブルに複数のアイテム(最大1000)が存在するかどうかを確認するには(1,000,000 rows +) EF/Linq/Sql Server db(Azureでホストされています)を使用して、追加する必要がありますか?複数のアイテムの存在を確認する最も効率的な方法

現時点では、私は非常にパフォーマンスが低下しています(ただし、最初はローカルのSQLデータベースで開発していましたが、それはずっと優れていました)。

このタスクでEFを残して、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 => !context.foos.Any(f => f.Serial == i.Serial)).ToList();コマンドで.Any() LINQコマンドを使用している間、私はちょうどローカルSQLデータベースに対してSQLプロファイラトレースを実行した、とEFは、それぞれの個々のSQLクエリとしてそれを実行することを発見importedFoosの項目ですので、そのメソッドを使用する際には利点がないようです。

答えて

4

2番目のスニペットは、Linq toオブジェクトクエリの一部としてEFクエリを実行しているため、なぜアイテムごとにクエリを実行するのですか。 dbへの1回のラウンドトリップを実行するには、1つのEFクエリーを実行する必要があります。

+0

ああ、ありがとう、私は過去の不要な.ToList()コールをやっているのを忘れてしまった。 – Ted

+0

@Ted 'importedFoos'が実際にあなたが不必要に実現したEFクエリである場合、これははるかに簡単です。それを具体化して、 'context.Foos.Except(importedFoos);と書いてください。そして、あなたは完了しており、最も効率的な実装もしています。 – Servy

関連する問題