Используйте Entity Framework для подключения к базе данных MySQL, работающей в контейнере Docker - PullRequest
0 голосов
/ 14 марта 2019

Я начал изучать ASP.NET Core MVC и пытаюсь создать приложение, которое использует базу данных. Я хотел интегрировать ORM, поэтому я выбрал Entity Framework Core.

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

dotnet ef migrations add Initial --context ReceptionistContext

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

dotnet ef database update --context ReceptionistContext

Я получаю эту ошибку:

info: Microsoft.EntityFrameworkCore.Infrastructure [10403]
Entity Framework Core 2.2.3-servicing-35854 инициализировал 'ReceptionistContext', используя поставщика 'Microsoft.EntityFrameworkCore.SqlServer' с параметрами: Нет

System.Data.SqlClient.SqlException (0x80131904): во время установления соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: поставщик TCP, ошибка: 35 - обнаружена внутренняя исключительная ситуация)

System.Net.Internals.SocketExceptionFactory + ExtendedSocketException (00000005, 6): нет такого устройства или адреса

в System.Net.Dns.InternalGetHostByName (строка hostName)
в System.Net.Dns.GetHostAddresses (строка hostNameOrAddress) в System.Data.SqlClient.SNI.SNITCPHandle.Connect (String имя_сервера, порт Int32, время ожидания TimeSpan) в System.Data.SqlClient.SNI.SNITCPHandle..ctor (String serverName, порт Int32, Int64 timerExpire, объект callbackObject, логическая параллель) в System.Data.SqlClient.SqlInternalConnectionTds..ctor (идентификатор DbConnectionPoolIdentity, SqlConnectionString connectionOptions, учетные данные SqlCredential, объект providerInfo, строковое значение newPassword, SecureString newSecurePassword, логический объект accessingDirectoryDirectorySense для объекта в System.Data.SqlClient.SqlConnectionFactory.CreateConnection (параметры DbConnectionOptions, DbConnectionPoolKey poolKey, объект poolGroupProviderInfo, пул DbConnectionPool, DbConnection owningConnection, пользовательские функции DbConnectionOptions) в System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection (пул DbConnectionPool, DbConnection owningObject, параметры DbConnectionOptions, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) в System.Data.ProviderBase.DbConnectionPool.CreateObject (DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) в System.Data.ProviderBase.DbConnectionPool.UserCreateRequest (DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) в System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, логический onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal & connection) в System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, TaskCompletionSource 1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource 1 повтор, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal & connection) в System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal (DbConnection externalConnection, DbConnectionFactory connectionFactory, TaskCompletionSource 1 retry, DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource 1 повтор, DbConnectionOptions userOptions) в System.Data.SqlClient.SqlConnection.TryOpen (TaskCompletionSource 1 retry) at System.Data.SqlClient.SqlConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(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.b__0 (DbContext c, TState s) в Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute [TState, TResult] (состояние TState, Func 3 operation, Func 3 verifySucceeded)в Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute [TState, TResult] (стратегия IExecutionStrategy, Func 2 operation, Func 2 verifySucceeded, состояние TState) в Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute [TState, TResult] (стратегия IExecutionStrategy, состояние TState, операция Func`2) в Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists (Boolean retryOnNotExists) в Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists () в Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists () в Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate (String targetMigration) в Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase (String targetMigration, String contextType) в Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase. <> c__DisplayClass0_1. <. ctor> b__0 () в Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute (действие Action)
ClientConnectionId: 00000000-0000-0000-0000-000000000000
При установке соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: поставщик TCP, ошибка: 35 - обнаружена внутренняя исключительная ситуация)

docker-compose.yml:

version: "3"
services:
    db:
      # get the image
      image: mysql:5.7
      # define the container name
      container_name: "mysql_database"
      # set up the envinronment
      environment:
        MYSQL_DATABASE: 'hospital_management'
        # Set up a user
        MYSQL_USER: 'app'
        # Set up the password
        MYSQL_PASSWORD: 'password'
        # Password for root access
        MYSQL_ROOT_PASSWORD: 'root'
      # persists the data outside the container
      volumes:
        - ./data:/var/lib/mysql
      # map the ports host:container
      ports:
        - "3308:3306"

appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "ReceptionistContext": "Data Source=127.0.0.1:3608"
  }
}

Наконец, app.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SQLite" Version="2.2.3" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.15" />
  </ItemGroup>

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

Спасибо!

Ответы [ 2 ]

3 голосов
/ 15 марта 2019

Есть несколько проблем с вашим кодом / конфигурацией.

Первое, что вы получаете исключение, которое говорит, что ваш контекст использует Microsoft.EntityFrameworkCore.SqlServer провайдера. Это означает, что вы пытаетесь подключиться к Microsoft SQL Server вместо MySql.

Причина в том, что в вашем контекстном классе у вас, вероятно, есть такая строка:

options.UseSqlServer(Configuration.GetConnectionString("ReceptionistContext")));

однако вам нужен вызов конфигурации, который говорит, что вы хотите использовать MySql:

options.UseMySql(Configuration.GetConnectionString("ReceptionistContext")));

Следующее, что вы в настоящее время не указываете базу данных, имя пользователя или пароль в строке подключения:

"ReceptionistContext": "Data Source=127.0.0.1:3608"

и вы пытаетесь подключиться к порту 3 6 08, но в файле для создания докера вы отображаете порт 3 3 08

  ports:
    - "3308:3306"

, поэтому попробуйте следующее для вашей строки подключения

"ReceptionistContext": "Server=127.0.0.1;Port=3308;Database=hospital_management;Uid=app;Pwd=password"

это должно соответствовать вашей конфигурации docker compose:

Environment:
    MYSQL_DATABASE: 'hospital_management'
    # Set up a user
    MYSQL_USER: 'app'
    # Set up the password
    MYSQL_PASSWORD: 'password'
0 голосов
/ 17 марта 2019

Как все упоминали выше, я не определил строки подключения.Таким образом, я добавил эти строки в appsettings.json:

"AllowedHosts": "*",
  "ConnectionStrings": {
    "HMContext": "Server=127.0.0.1;Port=3308;Database=hospital_management;Uid=app;Pwd=password"
  }

Другая проблема заключалась в том, что я использовал UseSql вместо UseMySql в Startup.cs.

У меня все еще были проблемы.Это произошло из-за того, что строки подключения не совпадают с подписью UseMySql (приведенные выше строки верны).

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

CREATE TABLE `__EFMigrationsHistory` ( `MigrationId` nvarchar(150) NOT NULL, `ProductVersion` nvarchar(32) NOT NULL, PRIMARY KEY (`MigrationId`) );
...