Solucionado (ver solução)
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!