#asp.net-mvc #entity-framework #docker #asp.net-core #docker-compose
#asp.net-mvc #entity-framework #docker #asp.net-core #docker-compose
Вопрос:
Я начал изучать ASP.NET Core MVC и я пытаюсь создать приложение, которое использует базу данных. Я хотел интегрировать ORM, поэтому я выбрал Entity Framework Core.
Я подготовил проект, следуя этому руководству. Я успешно выполнил миграцию с помощью
dotnet ef migrations add Initial --context ReceptionistContext
но я не могу обновить базу данных, работающую внутри моего контейнера Docker. Я хотел выполнить это действие с помощью
dotnet ef database update --context ReceptionistContext
Я получаю эту ошибку:
информация: Microsoft.EntityFrameworkCore.Инфраструктура[10403]
Ядро Entity Framework 2.2.3-обслуживание-35854 инициализировал ‘Recept Context’ с помощью поставщика ‘Microsoft.EntityFrameworkCore.SQLServer’ с параметрами: НетSystem.Data.SqlClient.SQLException (0x80131904): при установлении соединения с SQL Server произошла ошибка, связанная с сетью или конкретным экземпляром. Сервер не был найден или был недоступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: TCP Provider, ошибка: 35 — Было обнаружено внутреннее исключение)
System.Net.Internals.SocketExceptionFactory ExtendedSocketException (00000005, 6): нет такого устройства или адреса
в System.Net.Dns.InternalGetHostByName(строковое имя хоста)
в System.Net.Dns.GetHostAddresses(строка hostNameOrAddress) в System.Data.SqlClient.SNI.SNITCPHandle.Подключитесь (строковое имя сервера, порт Int32, тайм-аут TimeSpan) к System.Data.SqlClient.SNI.SNITCPHandle..ctor(Строковое имя сервера, порт Int32, timerExpire Int64, объект callbackObject, логическая параллель) к System.Data.SqlClient.SqlInternalConnectionTds..ctor (идентификатор DbConnectionPoolIdentity, SqlConnectionString ConnectionOptions, SqlCredential credential, Object providerInfo, строка NewPassword, SecureString newSecurePassword, логическое перенаправление Userinstance, SqlConnectionString userConnectionOptions, переподключение сессионных данных, логическая обработка applyTransientFaultHandling, Доступ к строке открыт) в System.Data.SqlClient.SqlConnectionFactory.Создайте соединение (DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, dbconnectionconnectionconnection Owning, DbConnectionOptions userOptions) в System.Data.База поставщиков.DbConnectionFactory.Создайте PooledConnection (пул DbConnectionPool, объект DbConnection owningObject, параметры DbConnectionOptions, пул DbConnectionPoolKey, пользовательские опции DbConnectionOptions) в системе.данные.База поставщиков.DbConnectionPool.Создайте объект (DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) в System.Data.База поставщиков.DbConnectionPool.Запрос пользователя (DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) в System.Data.База поставщиков.DbConnectionPool.Попробуйте getConnection (DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, логическое значение allowCreate, логическое значение onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternalamp; connection) в System.Data.База поставщиков.DbConnectionPool.Попробуйте установить соединение (DbConnection owningObject, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternalamp; connection)
1 повтор, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternalamp; connection) в System.Data.База поставщиков.DbConnectionInternal.Попробуйте открыть внутреннее подключение (DbConnection outerConnection, DbConnectionFactory ConnectionFactory, TaskCompletionSource
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 retry, DbConnectionOptions userOptions)
1 повтор, DbConnectionOptions userOptions) в System.Data.SqlClient.SqlConnection.Попробуйте открыть (TaskCompletionSource
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry)
2.b__0(DbContext c, TState s) в Microsoft.EntityFrameworkCore.SQLServer.Хранение.Внутренняя стратегия.SqlServerExecutionStrategy.Выполните[TState,TResult] (успешно проверено состояние TState, функция
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_03 operation, Func
3) в Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Выполните[TState,TResult] (IExecutionStrategy strategy, функция2 operation, Func
2 проверена успешно, состояние TState) в Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Выполните[TState,TResult] (стратегия IExecutionStrategy, состояние TState, операция Func`2) в Microsoft.EntityFrameworkCore.SQLServer.Хранение.Internal.SqlServerDatabaseCreator.Существует (логическая повторная попытка не существует) в Microsoft.EntityFrameworkCore.SQLServer.Хранение.Internal.SqlServerDatabaseCreator.Существует () в Microsoft.EntityFrameworkCore.Миграции.HistoryRepository.Exists() в Microsoft.EntityFrameworkCore.Миграции.Внутренний.Мигратор.Миграция (String TargetMigration) в Microsoft.EntityFrameworkCore.Design.Внутренний.Операции миграции.Обновленная база данных (String TargetMigration, String ContextType) в Microsoft.EntityFrameworkCore.Design.OperationExecutor.Обновленная база данных.<> c__DisplayClass0_1.<.ctor>b__0() в Microsoft.EntityFrameworkCore.Design.OperationExecutor.Операционная база.Выполнить (Действие action)
ClientConnectionId: 00000000-0000-0000-0000000000000000
При установлении соединения с SQL Server произошла ошибка, связанная с сетью или конкретным экземпляром. Сервер не был найден или был недоступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: TCP Provider, ошибка: 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 для подключения к ней. Я также убедился, что контейнер был запущен, когда я пытался выполнить обновление.
Спасибо!
Комментарии:
1. В вашей строке подключения не указана база данных для подключения, а также имя пользователя и пароль для использования.
2. Я подозревал, что это может быть проблемой, но я действительно не знал, что добавить. Это моя первая встреча с .net. Не могли бы вы, пожалуйста, добавить дополнительные сведения о том, как добавить их в настройки?
Ответ №1:
Существует несколько проблем с вашим кодом / конфигурацией.
Первое, что вы получаете исключение, в котором говорится, что ваш контекст использует Microsoft.EntityFrameworkCore.SqlServer
поставщика. Это означает, что вы пытаетесь подключиться к серверу Microsoft SQL вместо MySQL.
Причина в том, что в вашем классе context у вас, вероятно, есть строка, подобная этой:
options.UseSqlServer(Configuration.GetConnectionString("ReceptionistContext")));
однако вам нужен вызов config, который сообщает, что вы хотите использовать MySQL:
options.UseMySql(Configuration.GetConnectionString("ReceptionistContext")));
Следующее, что в настоящее время вы не указываете базу данных, имя пользователя или пароль в строке подключения:
"ReceptionistContext": "Data Source=127.0.0.1:3608"
и вы пытаетесь подключиться к порту 3608, но в вашем файле docker compose вы сопоставляете порт 3308
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'
Комментарии:
1. Большое вам спасибо, сэр. Я отредактировал строки конфигурации, но я все еще получаю сообщение «Произошла одна или несколько ошибок. (Не удается подключиться ни к одному из указанных хостов MySQL.)’. Контейнер запущен, и я могу успешно подключиться к нему с помощью workbench по адресу ‘127.0.0.1:3308’
2. Я использовал неправильный формат в строке подключения. Я отредактировал свой пост и исправил ошибку, чтобы соответствовать этому connectionstrings.com/mysql-connector-net-mysqlconnection
3. «Источником данных» должно быть «Сервер» в строке подключения.
4. Спасибо @ChrisPratt. Я только что отредактировал свой ответ и изменил источник данных на сервер
Ответ №2:
Как все упоминалось выше, у меня не было определенных строк подключения. Таким образом, я добавил эти строки в appsettings.json
:
"AllowedHosts": "*",
"ConnectionStrings": {
"HMContext": "Server=127.0.0.1;Port=3308;Database=hospital_management;Uid=app;Pwd=password"
}
Другая проблема заключалась в том, что я использовал UseSql
insted of UseMySql
в Startup.cs
.
У меня все еще были проблемы. Это произошло из-за того, что строки подключения не соответствовали подписи UseMySql
(приведенные выше строки верны).
После всего этого приложение подключилось к базе данных docker, но у меня все еще была ошибка, связанная с отсутствием таблицы миграций. Похоже, это ошибка, но ее можно устранить, запустив следующий скрипт:
CREATE TABLE `__EFMigrationsHistory` ( `MigrationId` nvarchar(150) NOT NULL, `ProductVersion` nvarchar(32) NOT NULL, PRIMARY KEY (`MigrationId`) );