4
respostas

Relacionamento um para um não funciona no add-migration

Inclui na classe Endereco public Cliente Cliente { get; set; } // para resolver o relacionamento 1:1

Porém ao gerar o add-migration Cliente Não deu certo, na classe Cliente foi criado EnderecoDeEntregaClienteId

    public class Endereco
    {
        public int Numero { get; internal set; }
        public string Logradouro { get; internal set; }
        public string Complemento { get; internal set; }
        public string Bairro { get; internal set; }
        public string Cidade { get; internal set; }
        public Cliente Cliente { get; set; }
    }


    public partial class Cliente : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Enderecos",
                columns: table => new
                {
                    ClienteId = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    Bairro = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Cidade = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Complemento = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Logradouro = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Numero = table.Column<int>(type: "int", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Enderecos", x => x.ClienteId);
                });

            migrationBuilder.CreateTable(
                name: "Clientes",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    EnderecoDeEntregaClienteId = table.Column<int>(type: "int", nullable: true),
                    Nome = table.Column<string>(type: "nvarchar(max)", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Clientes", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Clientes_Enderecos_EnderecoDeEntregaClienteId",
                        column: x => x.EnderecoDeEntregaClienteId,
                        principalTable: "Enderecos",
                        principalColumn: "ClienteId",
                        onDelete: ReferentialAction.Restrict);
                });

            migrationBuilder.CreateIndex(
                name: "IX_Clientes_EnderecoDeEntregaClienteId",
                table: "Clientes",
                column: "EnderecoDeEntregaClienteId",
                unique: true,
                filter: "[EnderecoDeEntregaClienteId] IS NOT NULL");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Clientes");

            migrationBuilder.DropTable(
                name: "Enderecos");
        }
    }


public class LojaContext : DbContext
    {
        public DbSet<Produto> Produtos { get; set; }
        public DbSet<Compra> Compras { get; set; }
        public DbSet<Promocao> Promocoes { get; set; }
        public DbSet<Cliente> Clientes { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Usado para PK composta
            modelBuilder.Entity<PromocaoProduto>().HasKey(pp => new { pp.PromocaoId, pp.ProdutoId });

            //Nome da tabela para classe não mapeada no contexto
            modelBuilder.Entity<Endereco>().ToTable("Enderecos");
            //Criar uma coluna na classe que não está mapeada na classe (ClienteId) -> shadow property (propriedade escondida)  
            modelBuilder.Entity<Endereco>().Property<int>("ClienteId");
            //criar PK para endereço
            modelBuilder.Entity<Endereco>().HasKey("ClienteId");
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=LojaDB;Trusted_Connection=true;");
        }
4 respostas

Coloca o código da sua classe de configuração dos relacionamentos aqui.

public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; internal set; }
        public Endereco EnderecoDeEntrega { get; set; }


    }

    public class Endereco
    {
        public int Numero { get; internal set; }
        public string Logradouro { get; internal set; }
        public string Complemento { get; internal set; }
        public string Bairro { get; internal set; }
        public string Cidade { get; internal set; }
        public Cliente Cliente { get; set; }
    }

Oi Fabio, acredito que seja apenas o nome gerado pela migration mesmo. Pois no banco o relacionamento será feito por chaves estrangeiras, onde a tabela cliente vai ter o id da tabela endereco. Como o nome do atributo é EnderecoDeEntrega e está dentro da classe Cliente, temos EnderecoDeEntregaCliente. Mas o relacionamento é feito pelo id então fica EnderecoDeEntregaClienteId.

Rolou algum problema de execução?

Abraço.

Olá, Fábio

Por favor experimente fazer essas mudanças no seu modelo. Os comentários estão no código abaixo:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
.
.
.
    // Configurar ClienteId como PK para Endereco
    modelBuilder.Entity<Endereco>().HasKey(e => e.ClienteId); 

    // Configure ClienteId como FK para Endereco
    modelBuilder.Entity<Endereco>().HasRequired(e => e.Cliente).WithOptional(c => c.Endereco); }
.
.
.
}

    public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; internal set; }
    public virtual Endereco EnderecoDeEntrega { get; set; } //mudei para virtual

    }

    public class Endereco
    {
        [Key, ForeignKey("Cliente")]
        public int EnderecoId { get; set; }  //adicionei esta propriedade

        public int Numero { get; internal set; }
        public string Logradouro { get; internal set; }
        public string Complemento { get; internal set; }
        public string Bairro { get; internal set; }
        public string Cidade { get; internal set; }

        public virtual Cliente Cliente { get; set; } //mudei para virtual
    }