Entity Framework Core a introduit les méthodes HasServiceTier et HasPerformanceLevel pour modifier l'édition d'un serveur Azure SQL. Vous pouvez les utiliser dans OnModelCreating comme ceci:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasServiceTier("Basic");
modelBuilder.HasPerformanceLevel("Basic");
}
Si vous utilisez Add-Migration Add-Migration, vous obtenez une migration comme celle-ci:
public partial class ChangedDatabaseServiceTierToBasic : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("SqlServer:EditionOptions", "EDITION = 'Basic', SERVICE_OBJECTIVE = 'Basic'");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.OldAnnotation("SqlServer:EditionOptions", "EDITION = 'Basic', SERVICE_OBJECTIVE = 'Basic'");
}
}
Cela semble fonctionner correctement, mais lorsque j'essaie d'appliquer cette migration à une base de données locale non Azure à des fins de développement, j'obtiens l'erreur suivante:
Microsoft.EntityFrameworkCore.Migrations[20402]
Applying migration '20200413102908_ChangedDatabaseServiceTierToBasic'.
Applying migration '20200413102908_ChangedDatabaseServiceTierToBasic'.
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
BEGIN
DECLARE @db_name NVARCHAR(MAX) = DB_NAME();
EXEC(N'ALTER DATABASE ' + @db_name + ' MODIFY (
EDITION = ''Basic'', SERVICE_OBJECTIVE = ''Basic'' );');
END
Failed executing DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
BEGIN
DECLARE @db_name NVARCHAR(MAX) = DB_NAME();
EXEC(N'ALTER DATABASE ' + @db_name + ' MODIFY (
EDITION = ''Basic'', SERVICE_OBJECTIVE = ''Basic'' );');
END
Microsoft.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near '.'.
at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite)
at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:d9f92b81-9916-48ee-9686-6d0f567ab86f
Error Number:102,State:1,Class:15
Incorrect syntax near '.'.
Je suppose que les commandes ne sont pas valides pour les bases de données non Azure. La question est donc la suivante: comment empêcher l'exécution de ces commandes sur des bases de données non Azure?
c#
azure
entity-framework
entity-framework-core
Tim Pohlmann
la source
la source
Réponses:
L'équipe EF Core est maintenant au courant du problème et l'a ajouté à son backlog: https://github.com/dotnet/efcore/issues/20682
Pendant ce temps, la solution de contournement officiellement recommandée ressemble à ceci:
Je l'ai modifié pour fonctionner sans connaître le nom de la base de données actuelle:
la source
Bien sûr,
EDITION
etSERVICE_OBJECTIVE
ne sont pas pris en charge pour les bases de données non Azure SQL.Vous devez exécuter vos commandes uniquement pour la base de données Azure. Pour les autres types de serveur SQL, vous devez manquer l'exécution de votre code.
Je suggère de détecter SQL Server Edition avant d'exécuter votre code.
À cet effet, vous pouvez ajouter une méthode d'extension:
Et à l'intérieur de votre
OnModelCreating
méthode, vous pouvez utiliser le code suivant:la source
Cela semble très mal, mais cela fonctionne:
la source