# Migrations

Este guia descreve o processo completo de configuração da **Connection String**, configuração do **DbContext**, criação e aplicação de **Migrations** usando **Entity Framework Core** com **SQL Server 2025** em **Docker**.

## Configurar a Connection String no appsettings.json

Definir a **String de Conexão** apontando explicitamente para o IP, evitando dependência de resolução de **localhost**.

```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=127.0.0.1,1433;Database=repository-pattern;User ID=sa;Password=Sql@2025Secure!;Encrypt=True;TrustServerCertificate=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
```

## Configurar o DbContext no Program.cs

Após a criação do **builder**, configurar o **DbContext** utilizando a **Connection String** definida no **appsettings.json**:

```csharp
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
{
    options.UseSqlServer(connectionString);
});
```

Com isso, o **AppDbContext** passar a estar disponível para injeção de dependência em toda a aplicação.

## Limpar e reconstruir o projeto

Antes de criar as **migrations**, limpar e reconstruir o projeto para garantir que não exista lixo de **build**.

Comandos:

```ps1
dotnet clean
dotnet build
```

Exemplo de execução:

```ps1
PS C:\dev\RepositoryStore> dotnet clean

Construir êxito em 2,9s
PS C:\dev\RepositoryStore> dotnet build
Restauração concluída (2,6s)
  RepositoryStore net10.0 êxito (10,6s) → bin\Debug\net10.0\RepositoryStore.dll

Construir êxito em 13,8s
```

Saída esperada: build construído com êxito.

## Verificar se o SQL Server está em execução no Docker

Considerando que o **SQL Server** foi configurado previamente em **Docker**, é necessário verificar se o container está ativo.

Será iniciado o processo de migração e para isso o banco de dados precisa estar sendo executado. Considerando que o banco de dados está sendo executado em **Docker** e foi configurado anteriormente no início do projeto, verificar se ele está sendo executado, se ele existe, caso esteja parado inicia-lo, verificar sua execução.&#x20;

```ps1
> wsl

~$ docker container ls | grep 2025
~$ docker container ls -a | grep 2025
9dc633ab7148   mcr.microsoft.com/mssql/server:2025-latest   "/opt/mssql/bin/laun…"   16 hours ago   Exited (137) 32 seconds ago             sqlserver2025
```

Caso o container esteja parado, inicia-lo:

```ps1
~$ docker container start 9dc633ab7148
9dc633ab7148
~$ docker container ls | grep 2025
9dc633ab7148   mcr.microsoft.com/mssql/server:2025-latest   "/opt/mssql/bin/laun…"   16 hours ago   Up 5 seconds   0.0.0.0:1433->1433/tcp, :::1433->1433/tcp   sqlserver2025
```

Adicionar ao **Migrations** com a execução de `dotnet ef migrations add`

```ps1
PS C:\dev\RepositoryStore> dotnet ef migrations add v1
Build started...
Build succeeded.
The Entity Framework tools version '9.0.2' is older than that of the runtime '10.0.0'. Update the tools for the latest features and bug fixes. See https://aka.ms/AAc1fbw for more information.
Done. To undo this action, use 'ef migrations remove'
```

O container deve estar exposto na porta 1433.

## Criar a migration inicial

Com o banco em execução e o projeto compilando corretamente, criar a migration:

```ps
dotnet ef migrations add v1
```

Exemplo de execução:

```ps
PS C:\dev\RepositoryStore> dotnet ef migrations add v1
Build started...
Build succeeded.
The Entity Framework tools version '9.0.2' is older than that of the runtime '10.0.0'. Update the tools for the latest features and bug fixes. See https://aka.ms/AAc1fbw for more information.
Done. To undo this action, use 'ef migrations remove'
PS C:\dev\RepositoryStore> dotnet tool update --global dotnet-ef
A ferramenta 'dotnet-ef' foi atualizada com êxito da versão '9.0.2' para a versão '10.0.0'.
PS C:\dev\RepositoryStore> dotnet ef --version
Entity Framework Core .NET Command-line Tools
10.0.0
```

Após a execução será criado o diretório **Migrations**, contendo os seguintes arquivos:

* **AppDbContextModelSnapshot**
* **YYYYMMDDHHMMSS\_v1**

<figure><img src="https://1384347261-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fjf2S758a19OniqOY9luE%2Fuploads%2F07wj7quAe8GOHQOzKogr%2Fimage.png?alt=media&#x26;token=27637ce7-db5b-4aa2-b58e-755293348f99" alt=""><figcaption></figcaption></figure>

## Atualizar a ferramenta dotnet-ef

Caso apareça o aviso de versão entre **runtime** e ferramentas, atualize o **dotnet-ef** com os comandos:

```ps
dotnet tool update --global dotnet-ef
dotnet ef --version
```

Aviso:

```
The Entity Framework tools version '9.0.2' is older than 
        that of the runtime '10.0.0'. 
Update the tools for the latest features and bug fixes. 
See https://aka.ms/AAc1fbw for more information.
```

Exemplo de atualização do **dotnet-ef**:

```
PS C:\dev\RepositoryStore> dotnet tool update --global dotnet-ef
A ferramenta 'dotnet-ef' foi atualizada com êxito da versão '9.0.2' 
        para a versão '10.0.0'.
        
PS C:\dev\RepositoryStore> dotnet ef --version
Entity Framework Core .NET Command-line Tools
10.0.0
```

A versão deve corresponder ao **runtime** utilizado.

## Validar conexão com o SQL Server via sqlcmd

Para validar conectividade e TLS, utilize o **sqlcmd**:

```
sqlcmd.exe -S localhost,1433 -U sa -P Sql@2025Secure! -C -N
```

Exemplo de execução com execução de comando simples:

```ps
PS C:\Dev\RepositoryStore> sqlcmd.exe -S localhost,1433 -U sa -P Sql@2025Secure! -C -N
1> SELECT @@VERSION
2> GO
                                                                                                                                                                                                                                                
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2025 (RTM) - 17.0.1000.7 (X64)
        Oct 21 2025 12:05:57
        Copyright (C) 2025 Microsoft Corporation
        Enterprise Developer Edition (64-bit) on Linux (Ubuntu 22.04.5 LTS) <X64>                                       

(1 row affected)
1>
```

Isso confirma conectividade, autenticação e criptografia.

Caso necessário:

* Atualizar o **Microsoft ODB Driver for SQL Server**&#x20;

{% embed url="<https://learn.microsoft.com/pt-br/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver17>" %}

* Instalar o **SqlCmd**

{% embed url="<https://learn.microsoft.com/pt-br/sql/tools/sqlcmd/sqlcmd-download-install?tabs=windows&view=sql-server-ver17>" %}

* Instalar o **WinGet**

{% embed url="<https://learn.microsoft.com/pt-br/windows/package-manager/winget/>" %}

Documentação oficial da Microsoft deve ser usada como referência.

## Aplicação a migration no banco de dados

Com tudo validado, aplique a **migration**:

```ps
dotnet ef database update
```

Exemplo de aplicação:

```ps
PS C:\Dev\RepositoryStore> dotnet ef database update 
Build started...
Build succeeded.
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (505ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      CREATE DATABASE [repository-pattern];
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (374ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
      IF SERVERPROPERTY('EngineEdition') <> 5
      BEGIN
          ALTER DATABASE [repository-pattern] SET READ_COMMITTED_SNAPSHOT ON;
      END;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
info: Microsoft.EntityFrameworkCore.Migrations[20411]
      Acquiring an exclusive lock for migration application. See https://aka.ms/efcore-docs-migrations-lock for more information if this takes too long.
Acquiring an exclusive lock for migration application. See https://aka.ms/efcore-docs-migrations-lock for more information if this takes too long.
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (25ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      DECLARE @result int;
      EXEC @result = sp_getapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session', @LockMode = 'Exclusive';
      SELECT @result
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
      BEGIN
          CREATE TABLE [__EFMigrationsHistory] (
              [MigrationId] nvarchar(150) NOT NULL,
              [ProductVersion] nvarchar(32) NOT NULL,
              CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
          );
      END;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT 1
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (27ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [MigrationId], [ProductVersion]
      FROM [__EFMigrationsHistory]
      ORDER BY [MigrationId];
info: Microsoft.EntityFrameworkCore.Migrations[20402]
      Applying migration '20251207144811_v1'.
Applying migration '20251207144811_v1'.
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (4ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      CREATE TABLE [Product] (
          [Id] int NOT NULL IDENTITY,
          [Title] NVARCHAR(160) NOT NULL,
          CONSTRAINT [PK_Product] PRIMARY KEY ([Id])
      );
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (11ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
      VALUES (N'20251207144811_v1', N'10.0.0');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      DECLARE @result int;
      EXEC @result = sp_releaseapplock @Resource = '__EFMigrationsLock', @LockOwner = 'Session';
      SELECT @result
Done.
```

Durante o processo:

* O banco de dados **repository-pattern** é criado
* A tabela **\_\_EFMigrationsHistory** é gerada
* As tabelas definidas no modelo são criadas
* A **migration** é registrada

## Resultado final

O banco de dados e suas tabelas foram criados com sucesso.

Neste cenário, o banco está sendo gerenciado e visualizado utilizando o **Microsoft Azure Data Azure**.

<figure><img src="https://1384347261-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fjf2S758a19OniqOY9luE%2Fuploads%2F4yEDSi0YvfBnWWfvhIFd%2Fimage.png?alt=media&#x26;token=843a6a38-2dc2-4afa-8c53-7fce56d6a3b8" alt=""><figcaption></figcaption></figure>
