我正在尝试对通过Azure托管身份连接的Azure SQL数据库运行EF6 Code First迁移。有几个迁移要运行。上一次迁移失败。此迁移与其他迁移不同,因为它在新架构中创建表。
这是在运行创建新架构的Entity Framework 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权限文档确定所需的权限。到目前为止,我已经将以下角色添加到了所包含的用户中,运行迁移的App Service以以下角色连接:
db_ddladmin
db_datareader
db_datawriter
db_securityadmin
db_owner
db_accessadmin
(请注意,其他迁移仅适用于db_ddladmin,db_datareader和db_datawriter)
2。以服务器管理员身份运行迁移
我尝试以SQL Server管理员用户身份运行迁移。这可行,但是我们不允许以生产系统的SQL Server管理员用户身份进行连接。
答案 0 :(得分: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。
我唯一的解决方法是用服务器admin创建架构,这并不理想。
答案 1 :(得分:0)
如果将 AUTHORIZATION
添加到 CREATE 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,因为我在那里遇到了问题)