EF Core получает результат из базы данных без значений триггера базы данных

В таблице я реализовал триггер базы данных для заполнения столбца вычисленным значением (столбец имеет имя ProjectCode). Я использую контроллеры веб-API для создания и извлечения записей из базы данных. Экземпляр моего DbContext вводится в контроллер.

Когда DbContext добавляет новый экземпляр сущности, а затем сохраняет его, возвращаемые данные не включают автоматически созданное значение для столбца. База данных показывает правильное значение в столбце для вновь вставленной строки. Даже при получении данных одним и тем же методом свойство показывает значение null.

Project project = new Project();
dbContext.Projects.Add(project);
await dbContext.SaveChangesAsync();

// When placing a debugger stop here, and checking the database, I can see that the value for ProjectCode is populated correctly by the database trigger
// project.Id has valid value, however project.ProjectCode is null

Project createdProject = await dbContext.SingleOrDefaultAsync(p => p.Id == project.Id);

// createdProject is not null, however createdProject.ProjectCode is null

После завершения веб-вызова и удаления контроллера и DbContext выполняется новый вызов веб-API для получения данных. DbContext используется таким же образом при вызове

await dbContext.SingleOrDefaultAsync(p => p.Id == project.Id)

ProjectCode тогда показывает, что он заполнен правильно.

Почему после добавления или немедленного извлечения он не отображается правильно, даже если строка в базе данных показывает, что она заполнена?

Ссылка: Learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/…

topsail 01.08.2024 02:38

@topsail, спасибо, очень приятно это знать, на самом деле мы все еще застряли на версии 6. Однако знание об изменении полезно для нашего обновления!

Superman.Lopez 01.08.2024 05:00
Стоит ли изучать 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
2
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Триггеры основаны на событиях. Таким образом, они выполняются на основе асинхронного события и не блокируют операцию, вызвавшую его выполнение.

Триггер, отвечающий на операцию вставки, выполняется после завершения вставки.

Я не уверен, как именно Entity Framework загружает обновленные значения, но это будет в одной транзакции, поэтому вы читаете только данные, которые были предоставлены во время этой транзакции, содержащей операцию вставки. (По умолчанию вы читаете зафиксированные данные)

Вы можете попытаться перезагрузить данные, хранящиеся в DbContext, вызвав

dbContext.Entry(project).ReloadAsync();

для обновления значений DbContext вместо запроса по его идентификатору. (В конце концов, возможно, ничего не изменится, но будет более понятно, что вы пытаетесь сделать).

Связанная информация:

СОЗДАТЬ ТРИГГЕР (Transact-SQL)

Метод EntityEntry.ReloadAsync(CancellationToken)

Хм триггеры бывают блокирующие и синхронные.

Dale K 31.07.2024 21:10

Ладно, моя вина. Триггеры синхронны, но события не возникают синхронно.

dropoutcoder 31.07.2024 21:13

Чего именно вы пытаетесь достичь? Вы не можете заранее рассчитать код проекта? Последовательность HILO не поможет?

dropoutcoder 31.07.2024 21:16
Triggers are event based. - нет, это неправда, триггеры запускаются в контексте той же транзакции, что и вставка/обновление/удаление и блокировка, и все или ничего, если триггер не работает, вставка/обновление/удаление завершается неудачно.
Dale K 31.07.2024 22:20

Более вероятный ответ заключается в том, что EF не ожидает изменения других значений, о которых он не знает, и поэтому не перечитывает данные. Вероятно, существует настройка, которая в таком случае заставит EF перечитать всю строку.

Dale K 31.07.2024 22:22
Ответ принят как подходящий

Если у вас есть вычисляемый столбец, вы можете настроить EF Core так, чтобы он всегда получал этот столбец, не допуская его использования в операциях INSERT и UPDATE:

modelBuilder.Entity<Project>()
    .Property(e => e.ProjectCode)
    .ValueGeneratedOnAddOrUpdate();

Это сработало, как и ожидалось, и реализовать было интуитивно понятно.

Superman.Lopez 01.08.2024 08:22

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