Когда Contains вызывается для коллекции IEnumerable, используется реализация .NET Core. Когда Contains вызывается для объекта IQueryable, используется реализация базы данных.
Вызов Contains для IQueryable обычно предпочтительнее по соображениям производительности. При использовании IQueryable фильтрация выполняется сервером базы данных. Если сначала создается IEnumerable, все строки должны возвращаться с сервера базы данных.
Вызов ToUpper снижает производительность. Код ToUpper добавляет функцию в предложение WHERE TSQL-оператора SELECT. Добавленная функция не позволяет оптимизатору использовать индекс. Учитывая, что SQL устанавливается без учета регистра, рекомендуется не использовать вызов ToUpper, когда он не требуется.
Отсюда: https://docs.microsoft.com/ru-ru/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-3.1