我有一个很大的字符串列表(超过30k),我需要使用Entity Framework Core检查表中不存在哪些字符串。
类似的事情,但没有发送每项检查请求:
var notFoundItems = hugeList.Where(c => !tableToCheck.Any(x => x.Id == c)).ToList();
我找到了答案,但是使用了T-SQL
答案 0 :(得分:2)
T-SQL可能是一种很好的方法,但是在您的情况下,您将必须创建一个临时表并进行联接。 30k不是太多的记录,因此在应用程序端比较记录可能会更简单。在这种情况下,您可以这样做:
var idList = tableToCheck.Select(x => x.id).ToList();
var notFoundItems = hugeList.Where(item => idList.All(id => id != item));
由于数据库中的字符串是ID,因此您可以做得更好,并使用HashSet and Contains方法,该方法的复杂度为O(1):
var idSet = tableToCheck.Select(x => x.id).ToHashSet();
var notFoundItems = hugeList.Where(item => !idSet.Contains(item));
最终,性能取决于数据库中数据集的大小。如果数据库表很大并且您必须获取数百万个ID,则T-SQL方法将更快。
答案 1 :(得分:0)
由于您已经有了T-SQL解决方案,因此使用Raw SQL Query是一个很好的例子。当然,在某些情况下,SQL查询无法用LINQ表示或LINQ语句无法生成优化的查询。
答案 2 :(得分:0)
您可以进行选择,以搜索表上存在的所有字符串并将其放在列表中。在检查了不存在的字符串之后。
示例:
var foundItems = tableToCheck
.Where(x => hugeList.Contains(x.id))
.Select(x => x.id)
.Distinct()
.ToList();
var notFoundItems = hugeList.Where(c => !foundItems.Any(x => x == c)).ToList();
这样,您只向数据库执行一个请求。