Entity Framework Core подключается к базе данных MSSQL через SSH-туннель

Я видел много сообщений, задающих похожие вопросы, но ни один из них не разрешил проблему, которая у меня есть.

Моя настройка такова:

  • Удаленный хост с базой данных: доступно на 127.0.0.1:1433
  • SSH-туннелирование: L5000 → 127.0.0.1:1433

Когда я ввожу имя сервера 127.0.0.1,5000 в SQL Management Studio, я могу подключиться к базе данных, которую я хочу.

Если правильно настроить строку подключения и запустить мое приложение, я получаю следующее исключение:

Type       : SqlException
Message    : 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Source     : Core .Net SqlClient Data Provider
HResult    : -2146232060
TargetSite : .ctor
----- INNER EXCEPTION -----
Type       : Win32Exception
Message    : The system cannot find the file specified
HResult    : -2147467259

Поскольку я могу подключиться через Management Studio, я предполагаю, что проблема связана с моей строкой подключения или чем-то, связанным с ядром Entity Framework Core. Вот несколько строк подключения, которые я тестировал:

Data Source=127.0.0.1,5000;Network Library=DBMSSOCN;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5
Data Source=127.0.0.1;port=5000;Network Library=DBMSSOCN;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5
Server=127.0.0.1;port=5000;Network Library=DBMSSOCN;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5
Server=127.0.0.1,5000;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5
Server=127.0.0.1;port=5000;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5
Server=tcp,127.0.0.1,5000;Initial Catalog=Mux;Integrated Security=False;Persist Security Info=False;User ID=...;Password=...;MultipleActiveResultSets=True;Connect Timeout=5;Encrypt=True;TrustServerCertificate=True;Application Name=Mux;ConnectRetryCount=3;ConnectRetryInterval=5

Кто-нибудь есть идея, почему это так?


Редактировать 1 Я провел еще несколько тестов; SQL Server Profiler не регистрирует активность, если я пытаюсь запустить приложение.

Кроме того, я попытался использовать этот пост, используя ... tcp:... вместо ... tcp,..... это тоже не сработало.

Я попытался добавить DataSource в Visual Studio - Test Connection: OK. Я даже скопировал строку подключения, отображаемую там, вставив ее в мое приложение, запустил ее - не работал. И просто, чтобы сказать: да, приложение действительно использует предоставленную строку подключения.

Являются ли Visual Studio и SQL Management Studio особым образом подключены к серверу, а не с помощью строки подключения?


Изменить 2 На основе ваших комментариев я хотел бы добавить следующую информацию:

Зависимости проекта:

  • Microsoft.EntityFrameworkCore.SqlServer v2.0.3
  • Microsoft.EntityFrameworkCore.Tools v2.0.3
  • Microsoft.VisualStudio.Web.CodeGeneration.Design v2.0.4

Полное сообщение журнала:

Type       : SqlException
Message    : 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Source     : Core .Net SqlClient Data Provider
HResult    : -2146232060
TargetSite : .ctor
Stacktrace : at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource'1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource'1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource'1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource'1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.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.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func'3 operation, Func'3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, Func'2 operation, Func'2 verifySucceeded, TState state)
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at ch.wuerth.tobias.mux.Data.DataContextFactory.GetInstance()
   at ch.wuerth.tobias.mux.plugins.PluginMusicBrainz.PluginMusicBrainz.Process(String[] args) in C:\Users\Tobias\Desktop\dev\mux-cli\plugins\PluginMusicBrainz\PluginMusicBrainz.cs:line 136
   at ch.wuerth.tobias.mux.Core.plugin.PluginBase.Work(String[] args)
   at ch.wuerth.tobias.mux.App.Program..ctor(String[] args) in C:\Users\Tobias\Desktop\dev\mux-cli\App\Program.cs:line 47
Data :
 -> [HelpLink.ProdName, Microsoft SQL Server]
 -> [HelpLink.EvtSrc, MSSQLServer]
 -> [HelpLink.EvtID, 2]
 -> [HelpLink.BaseHelpUrl, http://go.microsoft.com/fwlink]
 -> [HelpLink.LinkId, 20476]
----- INNER EXCEPTION -----
Type       : Win32Exception
Message    : The system cannot find the file specified
HResult    : -2147467259

(внутреннее исключение не имеет stacktrace, потому что оно должно быть неопределенным)

Мой DbContext инициализирует строку подключения следующим образом:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("..my connection string..");
}

Редактировать 3 Я очень полагаю, что проблема должна быть DbContext с инициализацией DbContext, как еще можно объяснить разные поведения MSSQL Studio и приложения.

Также для тех, кто ищет какой-то контекст: я разрабатываю это приложение. Помимо моей локальной среды разработки, у меня есть производственный сервер, на котором я развертываю свою главную ветку. На производственном сервере также есть отдельная база данных с данными производства, которые можно было бы ожидать. Проблема в том, что мой CLI для обработки данных (импорт, обработка и..) на производственном сервере генерирует исключение, вызванное данными, и я не могу воспроизвести ошибку в моей среде разработки. Вместо того, чтобы пытаться скопировать всю базу данных (это несколько гигабайт), мне показалось, что я просто пытаюсь подключиться к производственной базе данных из моей среды разработки. Это позволит мне отладить исключение и исправить проблему. Может быть, у кого-то есть альтернативная идея о том, как я могу отлаживать свое приложение с помощью живой базы данных?

Ответ 1

Ваше сообщение об ошибке содержит:

(поставщик: поставщик Named Pipes, ошибка: 40 - не удалось открыть соединение с SQL Server)

Открыли ли вы "Диспетчер конфигурации SQL Server" и обеспечили ли "Именованные каналы" включен? Этот параметр находится в трех местах.

Ответ 2

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

"ConnectionStrings": {
   "DbConnection": "Data Source=tcp:127.0.0.1,5000\\DBMSSOCN;Initial Catalog=mdstsbase;Integrated Security=false;User ID=user;Password=password;Application Name=application name"
}