Указанное имя экземпляра LocalDB недействительно: можно создавать миграции, но не запускать их.

Я создал новое решение XAF Blazor и смог запустить его для создания базы данных. Затем я добавил миграцию базы данных в соответствии с этим вопросом Однако, когда я запускаю миграцию из диспетчера пакетов, я получаю

Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SNI_PN11, error: 50 - Local Database Runtime error occurred. Specified LocalDB instance name is invalid.
)
 ---> System.ComponentModel.Win32Exception (0x89C5011B): Unknown error (0x89c5011b)
   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.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover, SqlAuthenticationMethod authType)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool)
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   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.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.OpenDbConnection(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext c, TState s)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(Boolean retryOnNotExists)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:-1983577829,State:0,Class:20
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. 
(provider: SNI_PN11, error: 50 - Local Database Runtime error occurred. Specified LocalDB instance name is invalid.
)

Этот вопрос не дублирует этот вопрос о подключении к SQL Server, поскольку программа могла получить доступ к базе данных до того, как я создал миграцию.

[Обновлять]

Код

    using DevExpress.ExpressApp.EFCore.Updating;
    using Microsoft.EntityFrameworkCore;
    using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
    using DevExpress.Persistent.BaseImpl.EF;
    using DevExpress.ExpressApp.Design;
    using DevExpress.ExpressApp.EFCore.DesignTime;
    using DevExpress.Persistent.Base;
    using Microsoft.EntityFrameworkCore.Design;
    namespace ExamBuddy.Module.BusinessObjects {
        public class ExamBuddyContextInitializer : DbContextTypesInfoInitializerBase {
            protected override DbContext CreateDbContext() {
                var builder = new DbContextOptionsBuilder<ExamBuddyEFCoreDbContext>()
                    .UseSqlServer(@";");
                return new ExamBuddyEFCoreDbContext(builder.Options);
            }
        }
        public class ExamBuddyContextFactory : IDesignTimeDbContextFactory<ExamBuddyEFCoreDbContext>
        {
            public ExamBuddyEFCoreDbContext CreateDbContext(string[] args)
            {
                var optionsBuilder = new DbContextOptionsBuilder<ExamBuddyEFCoreDbContext>();
                optionsBuilder.UseSqlServer(@"Integrated Security=SSPI;MultipleActiveResultSets=true;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=ExamBuddy;ConnectRetryCount=0;");
                return new ExamBuddyEFCoreDbContext(optionsBuilder.Options);
            }
        }
        [TypesInfoInitializer(typeof(ExamBuddyContextInitializer))]
        public class ExamBuddyEFCoreDbContext : DbContext {
            public ExamBuddyEFCoreDbContext(DbContextOptions<ExamBuddyEFCoreDbContext> options) : base(options) {
                 
            }
            public DbSet<ModuleInfo> ModulesInfo { get; set; }
            public DbSet<ModelDifference> ModelDifferences { get; set; }
            public DbSet<ModelDifferenceAspect> ModelDifferenceAspects { get; set; }
            public DbSet<PermissionPolicyRole> Roles { get; set; }
            public DbSet<PermissionPolicyRoleBase> RolesBase { get; set; }
            public DbSet<PermissionPolicyUser> Users { get; set; }
        }

[Обновлять]

Я попытался прокомментировать атрибут Dev Express TypesInfoInitializer, который я попытался добавить в следующем, но он не выполняется (ошибка не выдает), тогда как если я помещаю ошибку в метод IDesignTimeDbContextFactory, он выдаст

public class MigrationsContextFactory : IDbContextFactory<ExamBuddyEFCoreDbContext>
{
    public ExamBuddyEFCoreDbContext CreateDbContext()
    {
        throw new Exception("In Migration Context");
        var optionsBuilder = new DbContextOptionsBuilder<ExamBuddyEFCoreDbContext>();
        optionsBuilder.UseSqlServer(@"Integrated Security=SSPI;MultipleActiveResultSets=true;Pooling=false;Data Source=(localdb)\\mssqllocaldb;Initial Catalog=ExamBuddy;ConnectRetryCount=0;");
        return new ExamBuddyEFCoreDbContext(optionsBuilder.Options);
    }
}

Метод ExamBuddyContextFactory выполняет

[Обновлять]

Когда я редактирую строку подключения, чтобы использовать только 1 обратную косую черту, я вижу следующие сообщения в Visual Studio 2019

Обнаружен недоступный код

опечатка в строке

Таким образом, миграция будет сгенерирована с двойной обратной косой чертой в строке подключения, но не будет запущена.


person Kirsten Greed    schedule 30.11.2020    source источник


Ответы (1)


Сообщение об исключении сообщает о проблеме

Указанное имя экземпляра LocalDB недействительно

Недопустимая часть - двойная обратная косая черта в (localdb)\\mssqllocaldb внутри C # дословно строковый литерал

optionsBuilder.UseSqlServer(
    @"Data Source=(localdb)\\mssqllocaldb;Integrated Security=SSPI;MultipleActiveResultSets=true;Pooling=false;Initial Catalog=ExamBuddy;ConnectRetryCount=0;");
//  ^                       ^

Фактическое имя - (localdb)\mssqllocaldb (одинарная обратная косая черта), поэтому либо исправьте это, либо удалите дословный строковый префикс @.

Все это стандартные строковые правила C #, и обсуждать здесь нечего. Почему

Может создавать миграции, но не запускать их?

Это потому, что команда Add-Migration не пытается подключиться к базе данных, а подключение к базе данных лениво инициализируется только при необходимости, поэтому недопустимая строка подключения не обнаруживается. Команде по-прежнему необходимо создать экземпляр DbContext, чтобы получить доступ к model, и контекст должен быть настроен для определенного типа поставщика базы данных (поскольку EF Core создает отдельную модель для каждого типа поставщика базы данных), но кроме этого это не имеет ничего общего с реальной базой данных.

Однако команде Update-Database, очевидно, требуется подключение к базе данных, а также команда Remove-Migration, которая должна проверить, применена ли уже миграция. Вот почему эти команды не работают, а Add-Migration - успешно.

Вы можете легко проверить это, предоставив поддельную недопустимую строку подключения, например

optionsBuilder.UseSqlServer("Blah")'

и наблюдайте за тем же поведением, что и в OP.

person Ivan Stoev    schedule 03.12.2020
comment
Я обновил вопрос, чтобы показать свои проблемы, когда я изменяю строку подключения, чтобы использовать только 1 обратную косую черту. - person Kirsten Greed; 03.12.2020
comment
Где вы можете посоветовать что-то изменить в appsettings.json? Вы показали код для использования подхода создания контекста Из фабрики времени разработки - класс ExamBuddyContextFactory, который содержит проблему, упомянутую в ответе. Все, что вам нужно было сделать, это исправить этот код. Обновления / другие проблемы, которые у вас есть, не имеют отношения к делу. Кстати, убедитесь, что у вас есть только 1 класс, реализующий IDbContextFactory<ExamBuddyEFCoreDbContext>, иначе вы получите разные ошибки. - person Ivan Stoev; 03.12.2020
comment
Ключевым моментом использования фабрики времени разработки является то, что EFC не будет пытаться запускать код из вашего запуска, поэтому не должен иметь никакого отношения к настройкам и другим материалам, которые вы используете для настройки контекста во время выполнения. - person Ivan Stoev; 03.12.2020
comment
да. Обновил вопрос. - person Kirsten Greed; 03.12.2020
comment
Вы знаете, почему VS жалуется на одиночную обратную косую черту? - person Kirsten Greed; 03.12.2020
comment
Я тоже использую VS2019 (последняя версия). И много таких заявлений optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=MyDb;Trusted_Connection=True;". И не получать ошибок / предупреждений - в конце концов, это всего лишь строка. - person Ivan Stoev; 03.12.2020
comment
Я отключил Resharper, и предупреждение исчезло. - person Kirsten Greed; 04.12.2020