Возможно ли и как создать триггер с помощью Entity Framework Core

#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. Не могли бы вы предоставить репозиторий исходного кода, который воспроизводит проблему?