Pular para o conteúdo principal

CSharp FluentAPI Configuração individual de Entidades

 A depender da quantidade de entidades da sua aplicação e da complexidade da configuração pode ser interessante configurar as entidades individualmente. Segue abaixo um exemplo da configuração da entidade Compras.

C#

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace MeuProjeto.Compras

{

    // 4. Configuração Fluent API

    public class CompraConfiguration : IEntityTypeConfiguration<Compra>

    {

        public void Configure(EntityTypeBuilder<Compra> builder)

        {

            builder.HasKey(c => c.Id);

            builder.Property(c => c.DataCompra)

                   .IsRequired();

            builder.Property(c => c.ValorTotal)

                   .HasColumnType("decimal(18,2)");

            // Configurando CompraItem como Owned Entity Type (Owned Collection)

            builder.OwnsMany(c => c.Itens, item =>

            {

                item.WithOwner().HasForeignKey("CompraId");

                item.Property<int>("Id"); // Chave sombra implícita

                item.HasKey("Id");


                item.Property(i => i.Produto)

                    .IsRequired()

                    .HasMaxLength(150);


                item.Property(i => i.PrecoUnitario)

                    .HasColumnType("decimal(18,2)");

            });

            

            // Exemplo de configuração de navegação como Backing Field

            builder.Metadata.FindNavigation(nameof(Compra.Itens))

                            .SetPropertyAccessMode(PropertyAccessMode.Field);

        }

    }

}

Existem duas formas de invocar CompraConfiguration. A maneira mais limpa e escalável é instruir o seu DbContext a escanear o assembly (projeto) em busca de todas as classes que implementam IEntityTypeConfiguration. O EF Core localiza e aplica todas elas automaticamente de uma só vez. Isso é possível através do código a seguir:

using Microsoft.EntityFrameworkCore;
using System.Reflection;

namespace MeuProjeto.Infraestrutura.Contextos
{
    public class ComprasDbContext : DbContext
    {
        public ComprasDbContext(DbContextOptions<ComprasDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            // Procura todas as configurações no assembly atual e as aplica
            modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
            
            // Se as configurações estiverem em outro projeto/assembly, você pode usar:
            // modelBuilder.ApplyConfigurationsFromAssembly(typeof(CompraConfiguration).Assembly);
        }
    }
}

Mas, se você preferir ter controle total e registrar classe por classe explicitamente, você instancia a configuração diretamente dentro do método OnModelCreating, usando o operador new:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // Registrando manualmente com "new"
    modelBuilder.ApplyConfiguration(new CompraConfiguration());
    
    // Se tivesse a configuração do produto espelho:
    // modelBuilder.ApplyConfiguration(new ProdutoEspelhoConfiguration());
}

Por que funciona assim?
As configurações do Fluent API são lidas apenas uma vez durante todo o ciclo de vida da aplicação (na primeira vez que o DbContext é utilizado). O EF Core processa essas regras, monta o modelo de metadados do banco de dados na memória e o coloca em cache. Como não é uma operação executada a cada requisição, não há necessidade de gerenciá-la via injeção de dependência.

Comentários

Postagens mais visitadas deste blog

UML e comunicação entre Componentes

(conteúdo gerado com I.A.) Antes de abordarmos o conceito de Componentes, vale a pena analisar como um programador iniciante costuma estruturar uma aplicação. Geralmente, a escolha é construir um monólito tradicional, agrupando todas as classes de domínio (como Categoria, Produto, Compra, Venda, Pagamento, etc.) em uma única pasta de Entidades. Da mesma forma, criam-se pacotes globais para Repositórios, Serviços e Controllers. O grande problema dessa abordagem é que ela gera um forte acoplamento entre as classes e as camadas do sistema. À medida que a aplicação cresce, isso desencadeia uma série de dificuldades: Manutenção e modelagem complexas: As responsabilidades se misturam. Rapidamente, o código passa a ter diversos trechos onde as classes assumem funções que não deveriam ter, tornando a evolução do sistema confusa. Escalabilidade ineficiente: Para escalar o backend, é necessário replicar a aplicação inteira e todo o banco de dados. Além de consumir mais recursos, isso traz o ri...

Quando escolher Flask ou Quart no Python

Atualmente , considerando o suporte assíncrono já presente no Flask, a escolha entre Flask e Quart para uma API Server depende de vários fatores técnicos. Vejamos alguns critérios: Fonte:  https://pt.stackoverflow.com/questions/51268/qual-a-diferen%C3%A7a-entre-comunica%C3%A7%C3%A3o-ass%C3%ADncrona-e-s%C3%ADncrona Suporte Assíncrono : Flask : O Flask oferece suporte assíncrono por meio de extensões de terceiros, como  flask[async] . No entanto, seu desempenho assíncrono é inferior aos frameworks nativamente assíncronos. Quart : O Quart é uma reimplantação do Flask baseada no padrão ASGI (Asynchronous Server Gateway Interface). Ele utiliza E/S assíncrona em todo o código e é mais adequado para bases de código predominantemente assíncronas. Desempenho : Flask : Como aplicação WSGI, o Flask usa um único worker para cada ciclo de solicitação/resposta. Quando uma solicitação chega a uma visualização assíncrona, o Flask inicia um loop de eventos em uma thread, executa a função da vi...

Metodo para criar relacionamento entre tabelas sem dar erro cíclico EFCore

Quando estamos modelando o banco de dados no Entity Framework Core (ou em qualquer outra ferramenta) é muito comum criarmos o erro cíclico. Este erro ocorre devido ao banco de dados não conseguir determinar onde o relacionamento termina, causando um erro de loop. Vejamos uma situação real onde foi gerado esse problema: Um Professor leciona em várias Turmas, Um Professor leciona uma ou mais Disciplinas, Um Professor leciona determinadas Disciplinas em determinadas Turmas, Uma Turma tem muitos Professores, Em todas as Turmas tem 9 Disciplinas. Em todas as turmas podem ter até 9 Professores. Só por essa descrição já é possível perceber que os relacionamentos podem ser complexos de entender. E tem-se também o problema da navegação em via dupla: Professor-Turmas, Turma-Professores. Então, como modelar essas tabelas sem que o banco entre em loop? Para resolver esse problema no Entity Framework Core e evitar o erro de "Multiple Cascade Paths" (caminhos múltiplos de cascata) comum n...