Entity Framework Core 5.0 - Aquecendo as turbinas


  Preparando-se para a versão 5.0 do Entity Framework Core e apresentando as novidades.

Ja temos uma versão preview1 do Entity Framework Core 5.0 e vamos começar elencando os requisitos necessários para rodar o danado...

Ele requer o .NET Standard 2.1 o que implica que :

  • Ele pode ser executado no .NET Core 3.1 e não requer o .NET 5 (por enquanto...)
  • Pode ser executado em outras plataformas que suportam o .NET Standard 2.1
  • Não pode ser executado no .NET Framework nem no .NET Standard 2.0

Como instalar o EF Core 5.0 preview ?

Ele é distribuído exclusivamente como um conjunto de pacotes NuGet. Por exemplo, para adicionar o provedor SQL Server ao seu projeto, você pode usar o seguinte comando usando a ferramenta dotnet:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 5.0.0-preview.2.20159.4

Nota: Além destes pacotes você pode consultar as relação dos demais pacotes no link do artigo original.

Pode também fazer a instalação no VS 2019 via menu Tools -> Manage Nuget Package for Solutions, acionando a guia Browse e instalando o pacote Microsoft.EntityFrameworkCore.SqlServer.

Obs:Para obter a versão preview marque a caixa : Include prerelease

Abaixo vemos a janela Solution Explorer exibindo o pacote instalado em um projeto Console .NET Core usando a versão 3.1.201 do .NET Core:

Usando a ferramenta dotnet ef

Se você quiser usar a ferramenta de linha de comando dotnet ef precisa instalar este pacote como uma ferramenta global ou local pois ela não vem mais instalada no .NET Core SDK.

Assim primeiro você deve desinstalar qualquer versão previamente instalada :

dotnet tool uninstall --global dotnet-ef

A seguir instale a nova versão :

dotnet tool install --global dotnet-ef --version 5.0.0-preview.2.20120.8

Esta nova versão ainda pode ser usada com versões anteriores do EF Core.

Apresentando as novidades

A seguir vou listar as princpais novidades da nova versão.

1 - Logging

Esse recurso é funcionalmente semelhante ao Database.Log no EF6. Ou seja, fornece uma maneira simples de obter logs do EF Core sem a necessidade de configurar qualquer tipo de estrutura de log externo.

O EF Core substitui o Database.Log por um método LogTo chamado DbContextOptionsBuilder em AddDbContext ou OnConfiguring. Por exemplo:

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
                    => optionsBuilder.LogTo(Console.WriteLine);

Existem variações com sobrecargas para :

  • Definir o nível de log mínimo :   .LogTo (Console.WriteLine, LogLevel.Information)
  • Filtrar eventos específicos :   .LogTo (Console.WriteLine, new [] {CoreEventId.ContextInitialized, RelationalEventId.CommandExecuted})
     
  • Filtrar todos os eventos em categorias específicas:  .LogTo (Console.WriteLine, new [] {DbLoggerCategory.Database.Name}, LogLevel.Information)
     
  • Usar um filtro personalizado sobre o evento e o nível:  .LogTo (Console.WriteLine, (id, nível) => id == RelationalEventId.CommandExecuting)

2 - Obtendo o SQL gerado

O EF Core 5.0 apresenta o método de extensão ToQueryString que retornará o SQL que o EF Core gerará ao executar uma consulta LINQ. Por exemplo, o código:

var query = context.Set<cliente>().Where(c => c.City == city);
Console.WriteLine(query.ToQueryString())

Resulta na seguinte saída quando o provedor para o SQL Server:

DECLARE p0 nvarchar(4000) = N'London';

SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
WHERE [c].[City] = @__city_0
 

Observe que declarações para parâmetros do tipo correto também estão incluídas na saída. Isso permite copiar/colar no SQL Server Management Studio ou ferramentas semelhantes, para que a consulta possa ser executada para depuração/análise.

3 - Usando um atributo para indicar que uma entidade não possui chave

Agora, se uma entidade não possuir chave, podemos configurá-la usando o atributo Keyless.

[Keyless]
public class Endereco
{
    public string Rua { get; set; }
    public string Cidade { get; set; }
    public int Cep { get; set; }
}

Este recurso é útil quando você for mapear objetos de valor que não possuem chave.

4 - Alterando a string de conexão no DbContext inicializado

Agora é mais fácil criar uma instância de DbContext sem nenhuma string de conexão. Além disso, a conexão ou a string de conexão agora pode ser alterada na instância de contexto.

Isso permite que a mesma instância de contexto se conecte dinamicamente a bancos de dados diferentes.

5- Proxies de Controle de Alterações (Change Tracker)

Agora, o EF Core pode gerar proxies de em  tempo de execução que implementam automaticamente INotifyPropertyChanging e INotifyPropertyChanged.

Eles relatam alterações de valor nas propriedades da entidade diretamente ao EF Core, evitando a necessidade de verificar alterações. No entanto, os proxies vêm com seu próprio conjunto de limitações, portanto não são para todos.

6- Visualizações de depuração(Debug) aprimoradas

As exibições de depuração são uma maneira fácil de analisar os elementos internos do EF Core ao depurar problemas.

Para o EF Core 5.0, facilitamos a leitura do modelo e adicionamos um novo modo de depuração para entidades rastreadas no gerenciador de estado.

7- Visualização de Debug do Modelo

Agora você pode fazer uma busca detalhada na propriedade Model do DbContext no depurador de sua escolha e expanda a propriedade DebugView :

O LongView é a visualização do modelo que temos há algum tempo. O ShortView é novo e não inclui anotações de modelo, o que facilita a leitura.

8 - Visualização de depuração do State Manager

O state manager é um pouco mais oculto que o modelo. Para encontrá-lo, faça uma busca detalhada na propriedade ChangeTracker do DbContext no depurador de sua escolha e, em seguida, procure na propriedade StateManager e expanda o DebugView.

A ShortView do state manager mostra:

  • Cada entidade sendo rastreada
  • Seus principais valores da chave
  • O estado da entidade - um de Added, UnChanged, Modified ou Deleted.
  • Os valores das propriedades de uma chave estrangeira

9- Manipulação aprimorada da semântica Null do banco de dados

Os bancos de dados relacionais normalmente tratam NULL como um valor desconhecido e, portanto, não é igual a qualquer outro NULL.

O C#, por outro lado, trata NULL como um valor definido que compara igual a qualquer outro nulo. Por padrão, o EF Core converte consultas para que elas usem semântica NULL em C#.

O EF Core 5.0 melhora muito a eficiência dessas traduções.

10 - Propriedades do indexador

O EF Core 5.0 oferece suporte ao mapeamento de propriedades do indexador C#.

Isso permite que as entidades ajam como pacotes de propriedades onde as colunas são mapeadas para propriedades nomeadas no pacote.

11- Geração de restrições de verificação para mapeamentos enum

Agora, as migrações do EF Core 5.0 podem gerar restrições CHECK para mapeamentos de propriedades de enumeração. Por exemplo:

EnumColumn VARCHAR(10) NOT NULL CHECK (MyEnumColumn IN('Useful', 'Useless', 'Unknown'))

12 - Método IsRelational

Um novo método IsRelational foi adicionado além dos IsSqlServer, IsSqlite e IsInMemory existentes. Isso pode ser usado para testar se o DbContext está usando algum provedor de banco de dados relacional. Por exemplo:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (Database.IsRelational())
    {
        // código.
    }
}

Além dessas novidades temos mais recursos como as traduções de consultas para construções DateTime, byte array, Reverse, operador bitwise, etc.

Configura todos os detalhes no link:

https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-5-0-preview-1/

Em outro artigo vou mostrar alguns recursos funcionando na prática no .NET Core 3.1 com esta nova versão.

"Quem ama a sua vida perdê-la-á, e quem neste mundo odeia a sua vida, guardá-la-á para a vida eterna.
Se alguém me serve, siga-me, e onde eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o honrará."
João 12:25,26

Referências:


José Carlos Macoratti