如何使用EF Core选择列表中不在表中的值?

时间:2018-11-07 18:12:41

标签: c# entity-framework linq entity-framework-core ef-core-2.1

我有一个很大的字符串列表(超过30k),我需要使用Entity Framework Core检查表中不存在哪些字符串。

类似的事情,但没有发送每项检查请求:

var notFoundItems = hugeList.Where(c => !tableToCheck.Any(x => x.Id == c)).ToList();

我找到了答案,但是使用了T-SQL

3 个答案:

答案 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();

这样,您只向数据库执行一个请求。