#sql-server #entity-framework-core #database-trigger
#sql-сервер #entity-framework-core #база данных-триггер
Вопрос:
Возможно ли создать SQL-триггер с помощью Entity Framework Core.
Возможно, используя инструкцию в
protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
{
}
Или просто путем выполнения инструкций SQL в сценариях миграции
public override void Up()
{
}
Комментарии:
1. Триггеры сильно зависят от поставщика , поэтому, пожалуйста, добавьте тег, чтобы указать, используете ли вы
mysql
,postgresql
,sql-server
oracle
илиdb2
— или что-то совсем другое.2. Ах, хорошо. Триггер не является стандартным?
3. Теоретически: да — практически у каждой серьезной СУБД есть триггеры. Но точный синтаксис и их возможности довольно сильно различаются от продукта к продукту ….
4. Пока нет fluent API, поэтому вариант (2) —
migrationBuilder.Sql("CREATE TRIGGER …")
и т.д.5. И невозможно расширить fluent API для создания действия, которое заполнит метод Up()? Я думаю, нет, потому что я не знаю, насколько fluent API может сравниться со снимком. Я очень разочарован этой базовой версией EF, потому что я действительно ожидал улучшения в определении его модели и большего контроля над DB.
Ответ №1:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"create trigger .....");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"drop trigger <triggerName>");
}
Комментарии:
1. при генерации SQL происходит сбой, поскольку он пытается создать триггер из структурированной процедуры
2. @Chazt3n, можете ли вы привести пример, который вы пробовали?
3. спасибо, что напомнили мне об этом. Это НЕ ПРИВЕДЕТ К сбою, если вы не укажете —idempotent при генерации SQL. Я не знал, что это было изменено в нашем конвейере CI
Ответ №2:
Последнее.EfCoreTriggers пакет для создания SQL-триггеров с помощью свободного синтаксиса, который позволяет выполнять инструкции insert, update, upsert, delete, insert if not exists после того, как триггер сработал следующим образом
modelBuilder.Entity<Transaction>()
.AfterInsert(trigger => trigger
.Action(triggerAction => triggerAction
.Upsert(transaction => new { transaction.UserId },
insertedTransaction => new UserBalance { UserId = transaction.UserId, Balance = insertedTransaction.Sum },
(insertedTransaction, oldBalance) => new UserBalance { Balance = oldBalance.Balance insertedTransaction.Sum })));
Этот код будет переведен на sql и применен к миграциям с использованием
migrationBuilder.Sql()
Комментарии:
1. спасибо за эту библиотеку, к сожалению, когда я пытаюсь написать
modelBuilder.Entity<AvailabilitySettings>().AfterInsert(trigger => trigger .Action(ta => ta.Update<AvailabilitySettings>( (insertedEntity, searchedEntity) => insertedEntity.Id == searchedEntity.Id, (insertedEntity, foundEntity) => (new AvailabilitySettings(foundEntity) { Revision = foundEntity.Id })) ));
, ничего не генерируется в методе Up при выполненииdotnet ef migrations add AMigration
2. Использовали ли вы расширение. Используйте TRIGGERS() при настройке вашего DbContext?
3. Да, я сделал. Может быть, просто нужно рассказать. Мой dbcontext находится в отдельной библиотеке. И я использую строку подключения изнутри класса, жестко закодированную для команд миграции
4. Не могли бы вы предоставить репозиторий исходного кода, который воспроизводит проблему?