Элементы репозитория ядра EF не отслеживаются после вставки с помощью ExecuteSqlRaw (CommandText)

#c# #entity-framework-core #repository-pattern #aspnetboilerplate

#c# #entity-framework-core #репозиторий-шаблон #aspnetboilerplate

Вопрос:

Из-за повышения производительности я вставляю данные, выполняя необработанную команду sql. Все данные правильно вставлены в базу данных, но репозиторий не знает об их вставке. По сути, usersBeforeInsert и usersAfterInsert содержат одни и те же 3 записи.

Кроме того, после перезапуска приложения репозиторию по-прежнему не известно о пользователях, вставленных с помощью ExecuteSqlRaw(), извлекая только пользователей, которые существовали до ExecuteSqlRaw().

Кто-нибудь знает, как заставить _userRepository извлекать все данные из базы данных? Кстати, я использую asp.net шаблонный проект.

Вот пример кода:

 var usersBeforeInsert = await _userRepository.GetAllListAsync();      // 3
var commandText = GenerateInsertUsersSqlScript(users);
var context = _userRepository.GetDbContext();
var rowsAffected = context.Database.ExecuteSqlRaw(commandText);       // 85000
context.SaveChange()
var usersAfterInsert = await _userRepository.GetAllListAsync();      // 3
  

Комментарии:

1. Не могли бы вы немного расширить то, что вы подразумеваете под «репозиторий не знает о их вставке»? Вы имеете в виду, что репозиторий не может их извлечь? Кроме того, какой тип объекта, если _userRepository ?

2. все работает так, как должно… если вы хотите получить вставленные элементы после необработанной вставки, вам следует вызвать GetAllListAsync после вставки… редактировать: Также после перезапуска приложения… репозиторий все еще не в курсе … возможно, context.SaveChange() удаляет пользователей, которых нет в usersBeforeInsert (или commandText добавляет что-то в другую таблицу)

3. @MarleneHE Под «не в курсе» я имел в виду, что когда вы пытаетесь извлечь данные после команды ExecuteSqlRaw(), она возвращает только записи, которые были в базе данных до ExecuteSqlRaw() . По сути, usersBeforeInsert и usersAfterInsert содержат одни и те же 3 записи. Репозиторий имеет тип IRepository<Пользователь, длинный>.

4. Вы пытаетесь вставить // 85000 строки? Данные проверки успешно вставлены в базу данных. Проверьте, использует ли EF Core в вашем проекте кэш.

5. @Shone мы не можем догадаться, что делает этот «репозиторий». Несомненно то, что это не требуется. DbSet уже является репозиторием, DbContext — это единица работы. SaveChanges сохранит все изменения с момента последнего вызова. Анти шаблон «общего репозитория» значительно усложняет использование EF Core. Insert Возможно, вы выполняете 500 удалений на стороне, например

Ответ №1:

Ваш виновник — эта строка

 var usersBeforeInsert = await _userRepository.GetAllListAsync();
  

Поскольку платформа предполагает, что между этой строкой и этой строкой ничего не изменилось

 var usersAfterInsert = await _userRepository.GetAllListAsync();
  

Вы можете исправить это, не вызывая список до завершения необработанной вставки, или вы можете очистить набор изменений.

самый простой способ очистить набор изменений — создать новый _userRepository, но я предполагаю, что он, скорее всего, введен.