在我目前的项目(Net 5、asp;. NET Core),我们使用FluentMigrator来运行EF Core迁移,它可以完美地工作。我们正在建立Azure中的基础设施,以便通过托管身份进行通信,并且已经设置了一个系统,将托管身份从我们的(web)应用程序服务分配给我们的SQL服务器。
我们遵循了这个指南:https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi?tabs=windowsclient%2Cdotnetcore
但是,我们从FluentMigrator得到以下空指针引用:
FluentMigrator.Runner.Processors.SqlServer.SqlServer2016Processor[0]
There was an exception checking if table VersionInfo in (null) exists
System.AggregateException: One or more errors occurred. (Object reference not set to an instance of an object.)
---> System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.<AcquireTokenInteractiveDeviceFlowAsync>b__18_0(DeviceCodeResult deviceCodeResult)
at Microsoft.Identity.Client.Internal.Requests.DeviceCodeRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.ExecuteAsync(AcquireToken CommonParameters commonParameters, AcquireTokenWithDeviceCodeParameters deviceCodeParameters, CancellationToken cancellationToken)
at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.AcquireTokenInteractiveDeviceFlowAsync(IPublicClientApplication app, String[] scopes, Guid connectionId, String userId, SqlAuthenticationMethod authenticationMethod, CancellationTokenSource cts)
at Microsoft.Data.SqlClient.ActiveDirectoryAuthenticationProvider.AcquireTokenAsync(SqlAuthenticationParameters parameters)
--- End of inner exception stack trace ---
at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)
at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open()
at FluentMigrator.Runner.Processors.GenericProcessorBase.<>c__DisplayClass6_1.<.ctor>b__1()
我想这是因为FluentMigrator不能使用连接字符串连接到数据库:
"Server=tcp:<server-name>.database.windows.net;Authentication=Active Directory Device Code Flow; Database=<database-name>;"
但我可能错了:-)
在StartUp.cs
中我们像这样注册FluentMigrator:
public void ConfigureServices(IServiceCollection services)
{
services.AddFluentMigratorCore()
.ConfigureRunner(rb => rb
.AddSqlServer()
.WithGlobalConnectionString(databaseConnectionString)
.ScanIn(typeof(Startup).Assembly).For.Migrations());
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
using IServiceScope scope = app.ApplicationServices.CreateScope();
IMigrationRunner runner = scope.ServiceProvider.GetRequiredService<IMigrationRunner>();
runner.MigrateUp();
}
有没有人知道是否有可能在所有得到FluentMigrator与AD/托管身份在Azure工作?
任何帮助/提示都是非常感谢的。
提前感谢。
编辑:如果我们注释掉FluentMigrator注册,我们的应用服务运行良好。
FluentMigrator没有任何问题。这只是我有一个隧道的视野,并遵循微软的指导,他们把SqlAuthenticationProvider.SetProvider(...)
在services.AddDbContext<T>(...)
里面:-)把它移到AddDbContext<T>(..)
外面像这样使它工作:
SqlAuthenticationProvider.SetProvider(
SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow,
new ManagedIdentitySqlAuthProvider());
services.AddDbContext<BasketApiDbContext>(options =>
{
options.UseSqlServer(databaseConnectionString);
});