Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Tabela única de endereços com EFC

Olá pessoal, estou com uma dúvida no mapeamento de entidades no Entity Framework Core.

Tenho as tabelas de Fornecedor, Cliente e Endereço, descritas abaixo, e queria utilizar somente uma tabela para armazenar os endereços, com relação 1:N entre Cliente e Endereço e 1:N entre Fornecedor e Endereço.

Pensei em colocar dois campos no Endereço para guardar o ID e o Tipo do relacionamento, mas não consegui configurar corretamente no método OnModelCreating do contexto.

Também li em alguns fóruns que teria que criar um campo de ID e outro de navegação no Endereço para cada relacionamento que ele tiver, mas acredito que ter esses campos e utilizar somente um em cada registro não seria a forma ideal e "sujaria" a classe. Ainda mais que outros relacionamentos podem surgir, criando mais campos.

Qual seria a forma mais correta de mapear as classes para que o EFC crie as tabelas de forma correta?

    public class Cliente
    {
        public int ID { get; set; }
        public string Nome { get; set; }
        public string Cpf { get; set; }
    }
    public class Fornecedor
    {
        public int ID { get; set; }
        public string Nome { get; set; }
        public string CNPJ{ get; set; }
    }
public class Endereco
    {
        public int ID { get; set; }
        public string Descricao { get; set; }
        public string Numero { get; set; }
        public string CEP { get; set; }
        public LogradouroTipo Logradouro { get; set; }
        public string Rua { get; set; }
        public string Complemento { get; set; }
    }

PS: As classes são só um exemplo.

2 respostas
solução!

Rafael, boa tarde.

Só pra confirmar: um cliente/fornecedor pode ter vários endereços? E o endereço é só de um cliente/fornecedor, certo?

Seguindo essa premissa minha sugestão é colocar as chaves estrangeiras para cliente e fornecedor na própria classe de endereço. E isso é feito usando as propriedades de navegação. Veja:

public class Endereco
{
    public int ID { get; set; }
    public string Descricao { get; set; }
    public string Numero { get; set; }
    public string CEP { get; set; }
    public string Rua { get; set; }
    public string Complemento { get; set; }
    //propriedades de navegação
    public Cliente Cliente { get; set; }
    public Fornecedor Fornecedor { get; set; }
}

Daí a migração que gerei criou as 3 tabelas e na tabela de endereço duas chaves estrangeiras, uma para clientes e outra para fornecedores. Veja o método Up() da migração:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "Clientes",
        columns: table => new
        {
            ID = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            Nome = table.Column<string>(nullable: true),
            Cpf = table.Column<string>(nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Clientes", x => x.ID);
        });

    migrationBuilder.CreateTable(
        name: "Fornecedores",
        columns: table => new
        {
            ID = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            Nome = table.Column<string>(nullable: true),
            CNPJ = table.Column<string>(nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Fornecedores", x => x.ID);
        });

    migrationBuilder.CreateTable(
        name: "Enderecos",
        columns: table => new
        {
            ID = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            Descricao = table.Column<string>(nullable: true),
            Numero = table.Column<string>(nullable: true),
            CEP = table.Column<string>(nullable: true),
            Rua = table.Column<string>(nullable: true),
            Complemento = table.Column<string>(nullable: true),
            ClienteID = table.Column<int>(nullable: true),
            FornecedorID = table.Column<int>(nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Enderecos", x => x.ID);
            table.ForeignKey(
                name: "FK_Enderecos_Clientes_ClienteID",
                column: x => x.ClienteID,
                principalTable: "Clientes",
                principalColumn: "ID",
                onDelete: ReferentialAction.Restrict);
            table.ForeignKey(
                name: "FK_Enderecos_Fornecedores_FornecedorID",
                column: x => x.FornecedorID,
                principalTable: "Fornecedores",
                principalColumn: "ID",
                onDelete: ReferentialAction.Restrict);
        });

    migrationBuilder.CreateIndex(
        name: "IX_Enderecos_ClienteID",
        table: "Enderecos",
        column: "ClienteID");

    migrationBuilder.CreateIndex(
        name: "IX_Enderecos_FornecedorID",
        table: "Enderecos",
        column: "FornecedorID");
}

Espero que tenha ajudado.

Abraços!

Boa tarde Daniel.

Ajudou sim, obrigado.