Поделиться через


Другие заметки для SQL Server

Параметры базы данных SQL Azure

Note

Следует использовать UseAzureSql метод вместо UseSqlServer, когда подключаетесь к Azure SQL.

База данных SQL Azure предоставляет различные варианты ценообразования , которые обычно настраиваются на портале Azure. Однако если вы управляете схемой, используя миграции EF Core, вы можете настроить необходимые параметры через EF, и они будут применены в момент, когда EF создаёт базу данных.

Уровень служб базы данных (EDITION) можно указать с помощью HasServiceTier:

modelBuilder.HasServiceTier("BusinessCritical");

Максимальный размер базы данных можно указать с помощью HasDatabaseMaxSize:

modelBuilder.HasDatabaseMaxSize("2 GB");

Вы можете указать уровень производительности базы данных (SERVICE_OBJECTIVE) с помощью HasPerformanceLevel:

modelBuilder.HasPerformanceLevel("BC_Gen4_1");

Используйте HasPerformanceLevelSql для настройки эластичного пула, так как значение не является строковым литералом:

modelBuilder.HasPerformanceLevelSql("ELASTIC_POOL ( name = myelasticpool )");

Tip

Все поддерживаемые значения можно найти в документации ALTER DATABASE.

SaveChanges, триггеры и оператор OUTPUT

Когда EF Core сохраняет изменения в базе данных, он делает это оптимизированной техникой с помощью предложения T-SQL OUTPUT. К сожалению, предложение OUTPUT имеет некоторые ограничения; в частности, нельзя использовать с таблицами, которые имеют триггеры, например.

При возникновении ограничения, связанного с использованием предложения OUTPUT, его можно отключить в определенной таблице с помощью UseSqlOutputClause:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .ToTable(tb => tb.UseSqlOutputClause(false));
}

Это приведет к переходу EF на более старый, менее эффективный способ обновления таблицы.

Если большинство или все таблицы имеют триггеры, это можно настроить для всех таблиц модели с помощью следующего соглашения о построении модели:

public class NoOutputClauseConvention : IModelFinalizingConvention
{
    public virtual void ProcessModelFinalizing(
        IConventionModelBuilder modelBuilder,
        IConventionContext<IConventionModelBuilder> context)
    {
        foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
        {
            var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
            if (table is not null)
            {
                entityType.Builder.UseSqlOutputClause(false);
            }

            foreach (var fragment in entityType.GetMappingFragments(StoreObjectType.Table))
            {
                entityType.Builder.UseSqlOutputClause(false, fragment.StoreObject);
            }
        }
    }
}

Это эффективно вызывает UseSqlOutputClause на всех таблицах вашей модели, вместо того чтобы делать это вручную для каждой таблицы.