3
有沒有人知道什麼是最有效的方式是檢查存在多個項目(最多1000)在一個大的數據庫表(1,000,000行+),看看他們是否需要添加,使用EF/Linq/SQL Server數據庫(託管在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);
}
更新
我剛剛運行對本地SQL數據庫SQL事件探查器跟蹤,而在var foosToAddToDb = importedFoos.Where(i => !context.foos.Any(f => f.Serial == i.Serial)).ToList();
命令使用.Any()
LINQ命令,發現EF運行時,它爲每個單獨的SQL查詢項目importedFoos
,所以在使用該方法時看起來沒有任何優勢。
Ah謝謝Servy,會放棄這一切,我已經犯了不必要的.ToList()調用的過去。 – Ted
@Ted如果'importedFoos'實際上是一個EF查詢,你不必要的物化,那麼這很容易。只要不實現它並編寫'context.Foos.Except(importedFoos);'你就完成了,並且也是最有效的實現。 – Servy