SQL Server 的其他说明

Azure SQL 数据库选项

Note

应在连接到 Azure SQL 时使用 UseAzureSql 方法,而不是 UseSqlServer 方法。

Azure SQL 数据库提供了通常通过 Azure 门户配置的 多种定价选项 。 但是,如果使用 EF Core 迁移管理架构,则可以使用 EF 配置所需的选项,并在 EF 创建数据库时应用这些选项。

可以使用 HasServiceTier 指定数据库(EDITION)的服务层级:

modelBuilder.HasServiceTier("BusinessCritical");

可以使用 HasDatabaseMaxSize 指定数据库的最大大小:

modelBuilder.HasDatabaseMaxSize("2 GB");

可以使用 HasPerformanceLevel 指定数据库的性能级别(SERVICE_OBJECTIVE):

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,而无需为每个表手动执行此操作。