潜在优化的替代 linq 查询,用于在一组 ID 中查找不存在的记录
Potential Optimised alternative linq query for finding non Existent records within a set of Ids
假设我得到了一组 ID [整数],我想知道其中哪一个不存在于特定 Db table [例如 Table1] 中。目前我使用以下 EF 查询 [我的 EF 版本是 EF6,但我假设在这个特定场景中使用 EF6 或 EF Core 无关紧要]:
// Lets assume record with id = 9999 doesnt exist in the database
IEnumerable<int> Ids = new [] { 1 ,2 ,3, 4, 9999}
var nonExistentIds = Ids.Except(myDbContext.Table1.Select(x => x.Id)
.Intersect(Ids));
以上示例将 return [9999] 这是给定数组中不存在于数据库中的记录。
是否有潜在的更好的 linq 替代方案[我不是在寻找本机 sql 替代方案] 来发现不存在的记录?
我认为主要的替代方法是使用 .Distinct()
而不是 .Intersect(Ids)
。前者会 return 一个更大的数字列表,而后者需要将 ID 列表发送到 SQL 服务器。我不知道什么会更快,它可能最容易测试。
只要Ids
比较小,我就用Contains
:
var existingIds = myDbContext.Table1.Select(x => x.Id)
.Where(id => Ids.Contains(id))
.ToHashSet();
var nonExistentIds = ids.Where(id => !existingIds.Contains(id));
应该翻译成
SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Table1] AS [Extent1]
WHERE [Extent1].[Id] IN (1, 2, 3, 4)
然后使用 LINQ to Objects 反转结果。
你也可以用Except
反转:
var nonExistentIds = ids.Except(myDbContext.Table1.Select(x => x.Id)
.Where(id => Ids.Contains(id)));
Contains
相对于 Intersect
的好处是将 ID 列表发送到 SQL 服务器的方式 - Intersect
非常冗长地构造了一个 table , UNION ALL
会更快地溢出 SQL.
假设我得到了一组 ID [整数],我想知道其中哪一个不存在于特定 Db table [例如 Table1] 中。目前我使用以下 EF 查询 [我的 EF 版本是 EF6,但我假设在这个特定场景中使用 EF6 或 EF Core 无关紧要]:
// Lets assume record with id = 9999 doesnt exist in the database
IEnumerable<int> Ids = new [] { 1 ,2 ,3, 4, 9999}
var nonExistentIds = Ids.Except(myDbContext.Table1.Select(x => x.Id)
.Intersect(Ids));
以上示例将 return [9999] 这是给定数组中不存在于数据库中的记录。
是否有潜在的更好的 linq 替代方案[我不是在寻找本机 sql 替代方案] 来发现不存在的记录?
我认为主要的替代方法是使用 .Distinct()
而不是 .Intersect(Ids)
。前者会 return 一个更大的数字列表,而后者需要将 ID 列表发送到 SQL 服务器。我不知道什么会更快,它可能最容易测试。
只要Ids
比较小,我就用Contains
:
var existingIds = myDbContext.Table1.Select(x => x.Id)
.Where(id => Ids.Contains(id))
.ToHashSet();
var nonExistentIds = ids.Where(id => !existingIds.Contains(id));
应该翻译成
SELECT
[Extent1].[Id] AS [Id]
FROM [dbo].[Table1] AS [Extent1]
WHERE [Extent1].[Id] IN (1, 2, 3, 4)
然后使用 LINQ to Objects 反转结果。
你也可以用Except
反转:
var nonExistentIds = ids.Except(myDbContext.Table1.Select(x => x.Id)
.Where(id => Ids.Contains(id)));
Contains
相对于 Intersect
的好处是将 ID 列表发送到 SQL 服务器的方式 - Intersect
非常冗长地构造了一个 table , UNION ALL
会更快地溢出 SQL.