Entity Framework Core - Mapeando membros não públicos


Neste artigo vou mostrar como mapear membros não públicos usando o EF Core 2.0.

Já sabemos que o Entity Framework Core faz o mapeamento automático das propriedades públicas das entidades mas não faz o mapeamento para as propriedades não públicas.

Acontece que no paradigma da orientação a objetos o encapsulamento é um dos pilares e isso faz com que nem todos os membros de uma entidade sejam públicos.

Então como podemos mapear propriedades não públicas nas entidades ?

Como fazer com o que o Entity Framework Core reconheça estas propriedades ?

Os backing fields ou campos de suporte permitem que EF Core leia e/ou escreva para um campo em vez de uma propriedade. Isso pode ser útil quando o encapsulamento na classe está sendo usado para restringir o uso e/ou aprimorar a semântica  em torno do acesso aos dados pelo código do aplicativo, mas o valor deve ser lido ou escrito no banco de dados sem usar essas restrições. O EF Core descobre os campos para uma propriedade usando convenções de nomes.

Vejamos como podemos então realizar na prática o mapeamento para um propriedade privada em uma entidade.

Recursos usados:

Criando a solução e o projeto no VS Community

Abra o VS 2017 Community e clique em Visual C# -> .NET Core e escolha o template Console App(.NET Core) :

Informe o nome EFCore_Map_NonPublic e clique em OK;

Agora vamos incluir as seguintes referências via Nuget em nosso projeto:

No menu Tools clique em Nuget Package Manager e a seguir em Manage Nuget Packages for Solution;

Clique em Browse e localize o pacote e a seguir marque o projeto e clique em Install.

   

Repita o procedimento acima para cada pacote.

Criando o modelo de entidades

Crie uma pasta chamada Models no projeto e a seguir crie a classe Product conforme o código mostrado a seguir:

1- Product

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCore_Map_NonPublic.Models
{
    [Table("Products")]
    public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        private DateTime Timestamp { get; set; }
    }
}

Na pasta Models crie a classe de contexto chamada ProductDbContext que herda de DbContext e onde vamos definir o mapeamento:

5- ProductDbContext

using Microsoft.EntityFrameworkCore;
using System;

namespace EFCore_Map_NonPublic.Models
{
    public class ProductDbContext : DbContext
    {
        private readonly string _connectionString;
        public ProductDbContext()
        {
            _connectionString = @"Data Source=Macoratti;Initial Catalog=Cadastro;Integrated Security=True";
        }
        public DbSet<Product> Products { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(_connectionString);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
         
  modelBuilder.Entity<Product>().Property(typeof(DateTime), "Timestamp").IsRequired();
            base.OnModelCreating(modelBuilder);
        }
    }
}

Nesta classe PaisDbContext definimos a propriedade Products do tipo DbSet que vai mapear a entidade Product para a tabela Products.

Para mapear a propriedade privada usamos a linha de código no método OnModelCreating():

modelBuilder.Entity<Product>().Property(typeof(DateTime), "Timestamp").IsRequired();

Este método será chamado automaticamente quando o modelo estiver sendo incorporado na memória.

Verificando o mapeamento

Vamos agora definir o código no método Main() da classe Program conforme abaixo:

Executando o projeto e colocando um ponto de interrupção vemos que a variável produtos contém a propriedade privada TimeStamp.

"Deus nunca foi visto por alguém. O Filho unigênito (Jesus), que está no seio do Pai, esse o revelou."
João 1:18

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti