none
Problema ao inserir objeto complexo com WebAPI e EF Core RRS feed

  • Pergunta

  • Olá,

    Montei uma WebAPI onde possuo as seguintes classes:

    Pais.cs

        public class Pais
        {
            [Key]
            public Int32 id { get; set; }
            public String descricao { get; set; }
        }

    Estado.cs

        public class Estado
        {
            [Key]
            public Int32 id { get; set; }
            public virtual Pais pais { get; set; }
            public String descricao { get; set; }
            public String sigla { get; set; }
        }

    Cidade.cs

        public class Cidade
        {
            [Key]
            public Int32 id { get; set; }
            public virtual Estado estado { get; set; }
            public String descricao { get; set; }
        }

    Dentro do meu banco de dados tenho o pais BRASIL e o estado SÃO PAULO.

    Fiz uma implementação para adicionar uma nova cidade via método POST:

    public async Task<Cidade> insertAsync(Cidade item)
    {
    	context.Cidade.Add(item);
    	await context.SaveChangesAsync();
    
    	return await getById(item.id);
    }

    Ao chamar o métdo acima com o seguinte JSON:

    {
    	"estado": {
    		"id": 1,
    		"pais": {
    			"id": 1,
    			"descricao": "Brasil"
    		},
    		"descricao": "São Paulo",
    		"sigla": "SP"
    	},
    	"descricao": "Ribeirão Preto"
    }

    O sistema apresenta o seguinte erro na execução da linha "await context.SaveChangesAsync();":

    "Cannot insert explicit value for identity column in table 'Pais' when IDENTITY_INSERT is set to OFF."

    Não estou entendo porque a aplicação está tentando inserir o registro na tabela Pais também, sendo que já estou passando o ID dela e não estou passando a ID da Cidade.

    Alguém saberia me explicar onde estou errando?

    PS: Fiz a mesma codificação para inserir um pais e funcionou normalmente. Acredito que o erro só ocorra quando há chave estrangeira na entidade.

    Obrigado desde já!

    quinta-feira, 29 de junho de 2017 22:17

Todas as Respostas

  • Você informou na estrutura da sua tabela que a chave primaria é uma identity?
    sexta-feira, 30 de junho de 2017 02:01
  • Sim, estou definindo. De qualquer forma, segue minha classe gerada pelo migration:

    using System;
    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore.Migrations;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    namespace api.Migrations
    {
        public partial class Inicial : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.CreateTable(
                    name: "Pais",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        descricao = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Pais", x => x.Id);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Estado",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        descricao = table.Column<string>(nullable: true),
                        paisId = table.Column<int>(nullable: true),
                        sigla = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Estado", x => x.Id);
                        table.ForeignKey(
                            name: "FK_Estado_Pais_paisId",
                            column: x => x.paisId,
                            principalTable: "Pais",
                            principalColumn: "Id",
                            onDelete: ReferentialAction.Restrict);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Cidade",
                    columns: table => new
                    {
                        id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        descricao = table.Column<string>(nullable: true),
                        estadoId = table.Column<int>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Cidade", x => x.id);
                        table.ForeignKey(
                            name: "FK_Cidade_Estado_estadoId",
                            column: x => x.estadoId,
                            principalTable: "Estado",
                            principalColumn: "Id",
                            onDelete: ReferentialAction.Restrict);
                    });
    
                migrationBuilder.CreateIndex(
                    name: "IX_Cidade_estadoId",
                    table: "Cidade",
                    column: "estadoId");
    
                migrationBuilder.CreateIndex(
                    name: "IX_Estado_paisId",
                    table: "Estado",
                    column: "paisId");
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.DropTable(
                    name: "Cidade");
    
                migrationBuilder.DropTable(
                    name: "Estado");
    
                migrationBuilder.DropTable(
                    name: "Pais");
            }
        }
    }
    


    sexta-feira, 30 de junho de 2017 11:33
  • Bom dia, Thiago Derissi Poderoso. Tudo bem?

    Obrigado por usar o fórum MSDN,

    Poderia me informar se tua questão se trata de uma questão de "How to/Customização" ou "Break Fix/Erro"?

    Atenciosamente,


    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    sexta-feira, 30 de junho de 2017 14:40
    Moderador
  • Olá,

    How to

    sábado, 1 de julho de 2017 12:02
  • Qual versão do Entity Framework você está usando?

    Outra coisa o Entity está entendendo isso como uma inserção explicita favor colocar a ForeignKey.

     public class Cidade
    {
        [Key]
        public Int32 id { get; set; }
        public String descricao { get; set; }
    
        [ForeignKey("Estado ")]
        public int idEstado { get; set; }
        public virtual Estado estado { get; set; }
    }
    public class Estado
    {
        [Key]
        public Int32 id { get; set; } 
        public String descricao { get; set; }
        public String sigla { get; set; }
    
        [ForeignKey("Pais ")]
        public int idPais { get; set; } 
        public virtual Pais pais { get; set; }
    }   

    Isso deve-se ao fato de inserir navegadores e o entity entender que o virtual "Pais" por exemplo é uma entidade e precisa ser persistida no banco, então você precisa dizer quem é uma propriedade de navegação e mostrar pra ele quem é a propriedade PAI!



    Rafael Almeida
    Senior Developer .NET C#
    Development Leader at JAMSOFT Informática
    Criador e Mantenedor do Entity Framework Core for Firebird
    Contribuidor do Entity Framework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter



    segunda-feira, 13 de novembro de 2017 12:03