0

我正在尝试针对通过 Azure 托管标识连接的 Azure SQL 数据库运行 EF6 Code First 迁移。有几个迁移要运行。上次迁移失败。此迁移与其他迁移不同,因为它在新模式中创建表。

这是运行创建新架构的实体框架代码优先迁移时返回的错误:

System.Data.SqlClient.SqlException: The specified schema name "uuid@uuid" either does not exist or you do not have permission to use it.
CREATE SCHEMA failed due to previous errors.

我已经在数据库上记录了 SQL 命令,并且似乎失败的命令是

IF schema_id('MyNewSchema') IS NULL
EXECUTE('CREATE SCHEMA [MyNewSchema]')

出现错误:

<batch_information><failure_reason>Err 2759, Level 16, Server mysqldbname
CREATE SCHEMA failed due to previous errors.</failure_reason></batch_information>

以下是该系统的一些详细信息:

我尝试过的事情

1.添加角色

我尝试过的主要事情是使用 Microsoft 权限文档来确定需要哪些权限。到目前为止,我已将以下角色添加到运行迁移的应用服务连接的包含用户:

db_ddladmin
db_datareader
db_datawriter
db_securityadmin
db_owner
db_accessadmin

(请注意,其他迁移仅适用于 db_ddladmin、db_datareader 和 db_datawriter)

2. 以服务器管理员身份运行迁移

我尝试以 SQL Server 管理员用户身份运行迁移。这可行,但我们不允许以生产系统的 SQL Server 管理员用户身份连接。

4

2 回答 2

2

如果添加AUTHORIZATIONCREATE SCHEMA命令中,它会起作用。

因此,实体框架创建的语句需要看起来像这样:

IF schema_id('MyNewSchema') IS NULL
EXECUTE('CREATE SCHEMA [MyNewSchema] AUTHORIZATION [dbo]')

您可以通过覆盖来做到这一点ApplicationSqlServerMigrationsSqlGenerator

    protected override void Generate(EnsureSchemaOperation operation, IModel model, MigrationCommandListBuilder builder)
    {
        if (operation is null)
            throw new ArgumentNullException(nameof(operation));
        if (builder is null)
            throw new ArgumentNullException(nameof(builder));
        if (string.Equals(operation.Name, "dbo", StringComparison.OrdinalIgnoreCase))
        {
            return;
        }
        var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string));
        builder
            .Append("IF SCHEMA_ID(")
            .Append(stringTypeMapping.GenerateSqlLiteral(operation.Name))
            .Append(") IS NULL EXEC(")
            .Append(
                stringTypeMapping.GenerateSqlLiteral(
                    "CREATE SCHEMA "
                    + Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name)
                    + " AUTHORIZATION "
                    + Dependencies.SqlGenerationHelper.DelimitIdentifier("dbo")
                    + Dependencies.SqlGenerationHelper.StatementTerminator))
            .Append(")")
            .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator)
            .EndCommand();
    }

然后注册它:

        services.AddDbContextPool<ApplicationDbContext>(options =>
        {
            options.UseSqlServer("Your connection string");
            options.ReplaceService<IMigrationsSqlGenerator, ApplicationSqlServerMigrationsSqlGenerator>();
        });

(上面的代码适用于 EF Core,因为我在那里遇到了问题)

于 2021-03-05T07:42:02.660 回答
1

我刚刚使用 asp.net core 2.2 和 EF core 遇到了同样的问题。我试图使用托管标识来创建架构并得到了同样的错误。我发现这篇文章表明这​​是一个错误 - https://techcommunity.microsoft.com/t5/Azure-Database-Support-Blog/Lesson-Learned-54-The-specified-schema-name-name-domain-com /ba-p/369152

我唯一的解决方法是使用服务器管理员创建架构,这并不理想。

于 2019-11-03T14:16:32.920 回答