Потенциал Оптимизированный альтернативный запрос linq для поиска несуществующих записей в наборе идентификаторов - PullRequest
0 голосов
/ 08 апреля 2020

Допустим, мне дали массив Ids [целых чисел], и я хотел бы знать, какой из них не существует в конкретной таблице Db [например, 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));

Приведенный выше пример вернет [9999], который является запись в данном массиве, которая не существует в базе данных.

Возможно, существует лучшая альтернатива linq [я не ищу собственную альтернативу sql] для обнаружения несуществующих записей?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Пока 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 заключается в том, что список идентификаторов отправляется на SQL Сервер - Intersect очень многословно создает таблицу с UNION ALL, которая быстрее переполняется SQL.

0 голосов
/ 08 апреля 2020

Я думаю, что основной альтернативой будет использование .Distinct() вместо .Intersect(Ids). Первый вернул бы больший список чисел, а последним необходимо отправить список идентификаторов на сервер SQL. Я понятия не имею, что будет быстрее, это, вероятно, проще всего проверить.

...