Inquiridor
Problema ao inserir objeto complexo com WebAPI e EF Core

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á!
Todas as Respostas
-
-
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"); } } }
-
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.
-
-
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
- Editado Rafael Almeida - MVPMVP segunda-feira, 13 de novembro de 2017 12:07 renomear palavra