Использование Effort с расширениями EF. WhereBulkContains выдает System.Exception

Я пытаюсь провести модульное тестирование довольно простого метода репозитория, который извлекает некоторые объекты, соответствующие любому из предоставленного списка идентификаторов сопоставления строк.

Реализация использует расширение EF Extension WhereBulkContains, и я указываю столбец сущности, которому WhereBulkContain должен соответствовать, используя лямбду.

public List<MyEntity> GetEntitiesByMappingId(List<string> mappingIds)
    {
        if (!mappingIds?.Any() ?? true)
        {
            return new List<MyEntity>(0);
        }
        return this
            .context.MyEntity
            .AsNoTracking()
            .Include(e => e.ExtraData)
            .Include(e => e.OtherData)
            .WhereBulkContains(mappingIds, e => e.MappingId)
            .ToList();
    }

Когда мой тест запускает этот метод, он завершается сбоем из-за следующего основного исключения.

System.Exception
Oops! The `SkipInsertForInternalFeatures` option is only available for SQL Server, and PostgreSQL.
   at Z.BulkOperations.BulkOperation.()
   at Z.BulkOperations.BulkOperation.Execute()
   at Z.EntityFramework.Extensions.EntityBulkOperation`1.BulkInsert()
   at .BulkInsert[T](BulkOperation`1 this, DbContext context, List`1 list, Boolean isManager, List`1 entitiesToUpdate, Type type, String typeName)
   at .BulkInsert[T](DbContext this, BulkOperation`1 bulkOperation, IEnumerable`1 entities2, List`1 entitiesToUpdate)
   at DbContextExtensions.BulkInsert[T](DbContext this, IEnumerable`1 entities, Action`1 bulkOperationFactory)
   at Z.EntityFramework.Plus.WhereBulkContainsBuilder`1.BulkCopy(DbContext context, List`1 keyNames, IEnumerable`1 entities, Type type2)
   at Z.EntityFramework.Plus.WhereBulkContainsBuilder`1.WhereBulkContains(DbContext context, String commandText, List`1 commandTableBuilders, Boolean isNotCTE, Boolean isNotSelectOnly)
   at Z.EntityFramework.Plus.QueryHookCommandInterceptor.ApplyHook(DbCommand command, DbContext context, String hook, Boolean isNotCTE)
   at Z.EntityFramework.Plus.QueryHookCommandInterceptor.ReaderExecuting(DbCommand command, DbCommandInterceptionContext`1 interceptionContext)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)

Это известное ограничение Усилия? Или я пропустил какую-то конфигурацию, которая должна позволить этому работать?

Я использую Effort.EF6 версии 2.2.17 и версию 8.103.0 Z.EntityFramework.Extensions и Z.EntityFramework.Plus.EF6.

Упс! Опция SkipInsertForInternalFeatures доступна только для SQL Server и PostgreSQL. Я полагаю, вы не используете ни один из этих двух?

Ivan Petrov 02.07.2024 13:51

Почему бы и нет .Where(e => mappingIds.Contains(e.MappingId))?

Marius 02.07.2024 13:57

@IvanPetrov нет, я использую entityframework-effort.net , который представляет собой абстракцию в памяти именно для модульного тестирования EF-кода.

Alastair 02.07.2024 14:03

@Мариус, да, я могу переключиться на использование базового варианта Where, но это означает, что я теряю многие преимущества производительности entityframework-extensions.net/… .

Alastair 02.07.2024 14:11

Никаких преимуществ нет. Эта библиотека использует хаки для выполнения вещей, которые просто не подходят для ORM и в какой-то момент неизбежно выходят из строя. Посмотрите на стек вызовов, чтобы понять, в чем заключается хак. Чтобы заставить вас поверить, что вы можете фильтровать по тысячам идентификаторов (вы не можете), эта библиотека пытается ОБЪЕМНО ВСТАВИТЬ ваши идентификаторы во временную таблицу с помощью SqlBulkCopy. После этого он выполнит INNER JOIN с исходной таблицей по идентификаторам, чтобы получить соответствующие строки. Вы получите лучшую производительность и более удобный в обслуживании код, если будете использовать свой собственный код ETL.

Panagiotis Kanavos 02.07.2024 14:38

Что касается an in-memory abstraction precisely for unit testing EF code EF Core уже имеет поставщика в памяти для базового тестирования, а поставщик SQLite можно использовать в режиме в памяти для тестирования более сложных запросов.

Panagiotis Kanavos 02.07.2024 14:40

Сколько предметов изначально находится в mappingIds? Учитывая, что предложение IN(@id1,..), сгенерированное .Where(x=>mappingIds.Contains(x.Id)), работает с тысячами элементов, почему вы с самого начала пытаетесь фильтровать по более чем 1 тысяче отдельных идентификаторов? Что ты пытаешься сделать? Загрузить данные, например, на основе файла CSV?

Panagiotis Kanavos 02.07.2024 14:47
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Список поддерживаемых поставщиков для Z.EntityFramework.Extensions из пакета NuGet:

Поддержка: SQL Server, MySQL, Oracle, PostgreSQL, SQLite и других!

и из репозитория на github:

Поддержка нескольких поставщиков SQL:

  • SQL-сервер 2008+
  • SQL Azure
  • SQL компактный
  • MySQL
  • SQLite
  • PostgreSQL
  • Оракул

Effort.EF6 не указан ни в одном из поддерживаемых поставщиков.

Это объясняет сообщение об исключении, которое вы получаете:

System.Exception
Oops! The `SkipInsertForInternalFeatures` option is only available for SQL Server, and PostgreSQL.
   at Z.BulkOperations.BulkOperation.()

Это иронично, поскольку обе библиотеки опубликованы одним и тем же человеком (не сказано, что созданы, в итоге оказалось много старых объектов с открытым исходным кодом).

Panagiotis Kanavos 02.07.2024 14:43

@PanagiotisKanavos да, тоже был удивлен...

Ivan Petrov 02.07.2024 14:49

Другие вопросы по теме