简体   繁体   English

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

[英]How to select values in list that are NOT IN a Table using EF Core?

I have a quite big list of strings (30k+) and I need to check which ones do not exist on a table using Entity Framework Core.我有一个相当大的字符串列表 (30k+),我需要使用 Entity Framework Core 检查表中不存在哪些字符串。

Something like this but without sending a request per item to check:像这样但没有发送每个项目的请求来检查:

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

I found an answer but using T-SQL我找到了答案,但使用T-SQL

T-SQL can be a good approach, but in your case you would have to create a temporary table and make a join. T-SQL 可能是一种很好的方法,但在您的情况下,您必须创建一个临时表并进行连接。 30k is not too many records, so it will probably be easier to compare records on the application side. 30k 并不是太多的记录,因此在应用程序端比较记录可能会更容易。 In that case, you could do this:在这种情况下,你可以这样做:

var idList = tableToCheck.Select(x => x.id).ToList();
var notFoundItems = hugeList.Where(item => idList.All(id => id != item));

Since your strings from the database are IDs, you can do even better and use HashSet and Contains method, which has complexity of O(1):由于数据库中的字符串是 ID,因此您可以做得更好并使用 HashSet 和 Contains 方法,其复杂度为 O(1):

var idSet = tableToCheck.Select(x => x.id).ToHashSet();
var notFoundItems = hugeList.Where(item => !idSet.Contains(item));

Ultimately, the performance depends on the size of the data set in the DB.最终,性能取决于数据库中数据集的大小。 If the DB table is huge and you would have to fetch millions of IDs, then the T-SQL approach will be faster.如果 DB 表很大并且您必须获取数百万个 ID,那么 T-SQL 方法会更快。

Since you already have a T-SQL solution, this is a good case for using a Raw SQL Query .由于您已经有了 T-SQL 解决方案,因此这是使用原始 SQL 查询的好例子。 There will certainly be cases where a SQL query cannot be expressed in LINQ or the LINQ statement doesn't generate an optimized query.肯定会出现 SQL 查询无法在 LINQ 中表达或 LINQ 语句不会生成优化查询的情况。

You can make a select that search all the strings that exists on the table and put in a list.您可以选择搜索表中存在的所有字符串并将其放入列表中。 After you check what strings that not exists.在检查哪些字符串不存在之后。

Example:例子:

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

This way you do just one request to the db.这样您只需向数据库发出一个请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM