Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
18
respostas

Como ficaria usando Fluent API?

Como ficaria o relacionamento usando Fluent API? Gostaria de fazer no mesmo molde do curso, ou seja, sem definir uma chave primária para a entidade EmpresaEndereco.

private static void ConfiguraEmpresaEndereco(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<EmpresaEndereco>().ToTable("EmpresaEndereco");
            modelBuilder.Entity<EmpresaEndereco>().HasKey(c => c.EmpresaEnderecoId);
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.EmpresaEnderecoId).ValueGeneratedOnAdd();
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.Cep).HasMaxLength(20).IsRequired();
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.Logradouro).HasMaxLength(200);
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.Complemento).HasMaxLength(100).IsRequired();
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.Bairro).HasMaxLength(150);
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.Cidade).HasMaxLength(150);
            modelBuilder.Entity<EmpresaEndereco>().Property(c => c.UF).HasMaxLength(2);
            modelBuilder.Entity<EmpresaEndereco>().HasOne(e => e.Empresa).WithOne(e => e.Endereco);
        }
18 respostas

Fala, xará, tudo bem?

Basta que você defina a shadow property para a coluna EmpresaId, como mostrei no segundo vídeo da aula. Assim:

//...resto da configuração...
modelBuilder.Entity<EmpresaEndereco>()
  .Property<int>("EmpresaId");
modelBuilder.Entity<EmpresaEndereco>()
  .HasKey("EmpresaId");
//...resto da configuração...

E não se esqueça de informar qual é o tipo da shadow property (no caso int)!

Clareou?

[Respondido pelo instrutor Daniel acima]

Vou testar quando chegar em casa e te falo se resolveu. Obrigado por enquanto.

Professor não está dando certo.

Segue código:

namespace Unidade_CoreMVC.Entidades { public class Teste { public int TesteId { get; set; } public string Nome { get; set; } public TesteEndereco Endereco { get; set; } } }

namespace Unidade_CoreMVC.Entidades { public class TesteEndereco { public string Logradouro { get; set; } public Teste Teste { get; set; } } }

using Microsoft.EntityFrameworkCore; using Unidade_CoreMVC.Entidades;

namespace Unidade_CoreMVC.DAL.Contexto { public class BancoContexto : DbContext { public BancoContexto() { }

public BancoContexto(DbContextOptions options) : base(options) { }

public DbSet Teste { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().ToTable("Testes"); modelBuilder.Entity().Property(c => c.TesteId); modelBuilder.Entity().HasKey(c => c.TesteId); modelBuilder.Entity().Property(c => c.Nome).HasMaxLength(200).IsRequired();

modelBuilder.Entity().ToTable("Enderecos"); modelBuilder.Entity().Property("TesteId"); modelBuilder.Entity().HasKey("TesteId"); modelBuilder.Entity().Property(c => c.Logradouro).HasMaxLength(200).IsRequired(); //modelBuilder.Entity().HasOne(e => e.Teste).WithOne(e => e.Endereco); }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder .UseNpgsql("Host=localhost;Port=5432;Pooling=true;Database=Escola;User Id=postgres;Password=123456; "); } } } }

Estou usando banco de dados PostGreSQL.

Esqueci de mandar a migração. Segue abaixo:

public partial class Inicial : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "Enderecos", columns: table => new { TesteId = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), Logradouro = table.Column(type: "varchar(200)", maxLength: 200, nullable: false) }, constraints: table => { table.PrimaryKey("PK_Enderecos", x => x.TesteId); });

migrationBuilder.CreateTable( name: "Testes", columns: table => new { TesteId = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), Nome = table.Column(type: "varchar(200)", maxLength: 200, nullable: false) }, constraints: table => { table.PrimaryKey("PK_Testes", x => x.TesteId); table.ForeignKey( name: "FK_Testes_Enderecos_TesteId", column: x => x.TesteId, principalTable: "Enderecos", principalColumn: "TesteId", onDelete: ReferentialAction.Cascade); }); }

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

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

Estou usando o framework core 2.0

Daniel, seguem meus comentários.

Depois tenta editar suas mensagens para formatar o código, igual fez na primeira mensagem. Fica mais fácil para as pessoas lerem, entenderem e por conseguinte ajudá-lo, ok?

Sobre o problema, não está dando certo em que momento? Está dando algum erro? Se sim, coloca aqui o texto com a exceção. Reparei que você criou uma shadow property chamada TesteId mas não informou o tipo dela. Deveria dar erro ao executar o comando Add-Migration. Parece que o código da migração não está sincronizado com o código da configuração.

Também observei que a migração vai tentar criar uma coluna TesteId como chave primária, gerando um valor automaticamente sempre que um registro for incluído. Por causa desse código aqui:

new { TesteId = table.Column(type: "int4", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),

Isso está acontecendo porque você comentou a criação da chave estrangeira aqui:

//modelBuilder.Entity().HasOne(e => e.Teste).WithOne(e => e.Endereco); }

Testa lá e volta aqui!

Essa é minha tabela Teste

namespace Unidade_CoreMVC.Entidades

{

    public class Teste

    {

        public int TesteId { get; set; }

        public string Nome { get; set; }

        public TesteEndereco Endereco { get; set; }

    }

}

Minha tabela TesteEndereço

namespace Unidade_CoreMVC.Entidades
{
    public class TesteEndereco
    {
        public string Logradouro { get; set; }
        public Teste Teste { get; set; }
    }
}

Meu contexto

using Microsoft.EntityFrameworkCore;
using Unidade_CoreMVC.Entidades;

namespace Unidade_CoreMVC.Contexto
{
    public class BancoContexto : DbContext
    {
        public DbSet<Teste> Testes { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder
                .Entity<Teste>()
                .ToTable("Teste");
            modelBuilder
                .Entity<Teste>()
                .Property(x => x.TesteId).UseNpgsqlSerialColumn();
            modelBuilder
                .Entity<Teste>()
                .HasKey(x => x.TesteId);

            modelBuilder
                .Entity<TesteEndereco>()
                .ToTable("Enderecos");
            modelBuilder
                .Entity<TesteEndereco>()
                .Property<int>("TesteId");
            modelBuilder
                .Entity<TesteEndereco>()
                .HasKey("TesteId");
            modelBuilder
                .Entity<TesteEndereco>()
                .HasOne(x => x.Teste)
                .WithOne(x => x.Endereco);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseNpgsql("Host=localhost;Port=5432;Pooling=true;Database=Escola;User Id=postgres;Password=123456; ");
        }
    }
}

Informações do console:

PM> Add-Migration Inicial
To undo this action, use Remove-Migration.
PM>

A migração gerada

using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Unidade_CoreMVC.Contexto.Migrations
{
    public partial class Inicial : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Enderecos",
                columns: table => new
                {
                    TesteId = table.Column<int>(nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
                    Logradouro = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Enderecos", x => x.TesteId);
                });

            migrationBuilder.CreateTable(
                name: "Teste",
                columns: table => new
                {
                    TesteId = table.Column<int>(nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
                    Nome = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Teste", x => x.TesteId);
                    table.ForeignKey(
                        name: "FK_Teste_Enderecos_TesteId",
                        column: x => x.TesteId,
                        principalTable: "Enderecos",
                        principalColumn: "TesteId",
                        onDelete: ReferentialAction.Cascade);
                });
        }

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

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

Dependências do projeto:

Microsoft.EntityFrameworkCore.Tools (2.0.1)

Npgsql.EntityFrameworkCore.PostgreSQL (2.0.0)

Estou usando PostGreSQL 10

Não esta dando erro mas, não me mostra o warning avisando sobre a shadow como mostra no curso. E a migração não esta do jeito que eu quero.

Vou criar um projeto com esse código para eu testar aqui. Mais tarde retorno.

Fala, xará!

Testei aqui e percebi que você inverteu a ordem na criação da chave estrangeira. Faça o seguinte na configuração:

//...resto da configuração
modelBuilder
  .Entity<Teste>()
  .HasOne(x => x.Endereco)
  .WithOne(x => x.Teste);

Assim o relacionamento será criado corretamente na tabela de endereço, fazendo com que TesteId seja tanto a chave primária quanto a chave estrangeira.

Professor, muito obrigado pela atenção.

Finalmente descobri onde estava o erro (Microsoft.EntityFrameworkCore.Tools (1.1.1).

Na versão 1.1.0 ele não estava entendendo a propriedade do tipo shadow.

Agradeço muito pela atenção e gostaria de deixar aqui registrado que gostei muito do curso q vc ministrou. Foi muito bom pra mim.

solução!

Tranquilo, Daniel.

Qualquer outra dúvida ou comentário, não hesite em usar o fórum! Peço por gentileza marcar esse tópico como solucionado.

Abraços!