ENTITY FRAMEWORK SALVANDO REGISTRO EM BRANCO

MRSILVA 19/10/2017 19:50:21
#477265
Olá.
Preciso de uma ajuda para resolver um problema na gravação de registro entre tabelas relacionadas, tenho um relacionamento de um para um mapeado através do Entity Framework, mas quando salvo no banco de dados está sendo criado um registro correto e um em branco na tabela Pessoa.

Modelo:

  {
[Table([Ô]Pessoa[Ô])]
public class Pessoa : EntityBase {

}




[DisplayName(displayName: [Ô]nome[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 80)]
public string nome { get; set; }

[DisplayName(displayName: [Ô]NomeFantasia[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 80)]
public string nomeFantasia { get; set; }


[DisplayName(displayName: [Ô]Tipo[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: false)]
public int tipoPessoa { get; set; }




}
}


[Table([Ô]Fornecedor[Ô])]
public class Fornecedor : Pessoa
{

public Fornecedor()
{

// this.pessoa = new Pessoa();
}


[Browsable(false)]
[DataObjectField(false, true, false)]

[ForeignKey([Ô]pessoa[Ô])]
[Index(IsUnique = true)]
public int IdPessoa { get; set; }
public virtual Pessoa pessoa { get; set; }

[DisplayName(displayName: [Ô]CNPJ/CPF[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 14)]
public string inscricaoFed { get; set; }

[DisplayName(displayName: [Ô]Inscricão estadual[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 14)]
public string inscricaoEst { get; set; }



Estou salvando da seguinte forma:

public void AdicionaFornecedor(Fornecedor fornecedor, int idPessoa)
{

fornecedor.IdPessoa = idPessoa;
Db.Fornecedor.Add(fornecedor);
SalvarBd();
}


Por favor alguém poderia me ajudar como corrigir isso. Desde já agradeço.
JABA 19/10/2017 20:14:51
#477266
Resposta escolhida
Sinceramente, não sei como o Entity está trabalhando com herança atualmente, mas acho que a propriedade [Ô]IdPessoa[Ô] teria que ir na classe Pessoa.
MRSILVA 19/10/2017 21:03:07
#477267
Jabá Obrigado pelo ajuda.

Esqueci de postar que a chave primaria da classe pessoa é herdada da classe EntityBase.

Quanto a chaves acredito que esteja correto já que o banco de dados é criado corretamente com os devidos relacionamentos.

Somente quando vou gravar um objeto fornecedor que cria um registro na tabela pessoa com id e o restante dos campos como null.
JABA 19/10/2017 22:14:20
#477268
Citação:

[ForeignKey([Ô]pessoa[Ô])]
[Index(IsUnique = true)]
public int IdPessoa { get; set; }



Mas você está declarando ele como uma chave estrangeira na classe [Ô]Fornecedor[Ô], pode ser que esteja dando conflito aí. Retire isso e trabalhe com a chave primária da classe base EntityBase.

Citação:

public virtual Pessoa pessoa { get; set; }



Eu também não consigo compreender muito bem o motivo de se criar uma herança e depois usá-la como composição na mesma entidade. Por que é necessário manter a propriedade acima? Isso é alguma convenção do Entity?

Veja esse links, talvez possa te ajudar:

medium.com/@fulviocanducci/entity-framework-heran%C3%A7a-73d4223ab776

www.dotnettricks.com/learn/entityframework/understanding-inheritance-in-entity-framework

www.entityframeworktutorial.net/code-first/inheritance-strategy-in-code-first.aspx


MRSILVA 20/10/2017 01:03:09
#477269
Muito obrigado Jaba pela orientação .

Meu modelo estava errado agora estou conseguindo inserir registro sem criar mais um em branco.

Meu modelo ficou da seguinte forma:

  [Table([Ô]Pessoa[Ô])]
public class Pessoa : EntityBase
{

public Pessoa()
{

//this.enderecos = new HashSet<Endereco>();
//this.fornecedores = new HashSet<Fornecedor>();


}

[DisplayName(displayName: [Ô]nome[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 80)]
public string nome { get; set; }

[DisplayName(displayName: [Ô]NomeFantasia[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 80)]
public string nomeFantasia { get; set; }


[DisplayName(displayName: [Ô]Tipo[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: false)]
public int tipoPessoa { get; set; }

[Table([Ô]Fornecedor[Ô])]
public class Fornecedor : EntityBase
{

public Fornecedor()
{

// this.pessoa = new Pessoa();
}


[Browsable(false)]
[DataObjectField(false, true, false)]


[Index(IsUnique = true)]
public int PessoaId { get; set; }
public virtual Pessoa pessoa { get; set; }

[DisplayName(displayName: [Ô]CNPJ/CPF[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 14)]
public string inscricaoFed { get; set; }

[DisplayName(displayName: [Ô]Inscricão estadual[Ô])]
[DataObjectField(primaryKey: false, isIdentity: false, isNullable: true)]
[StringLength(maximumLength: 14)]
public string inscricaoEst { get; set; }


Quanto:
Citação:

Mas você está declarando ele como uma chave estrangeira na classe [Ô]Fornecedor[Ô], pode ser que esteja dando conflito aí. Retire isso e trabalhe com a chave primária da classe base EntityBase.

Citação:


Como classe fornecedor estava herdando a classe Pessoa e classe pessoa está herdando a classe entityBase o Entity Framework criava a minha chave primaria para classe fornecedor, por isso que pareceu estranho, ou seja minha classe fornecedor tinha chave primaria e a chave estrangeira, bom não sei sé isso mesmo que você questionou.
JABA 20/10/2017 02:53:00
#477270
Citação:

Como classe fornecedor estava herdando a classe Pessoa e classe pessoa está herdando a classe entityBase o Entity Framework criava a minha chave primaria para classe fornecedor, por isso que pareceu estranho, ou seja minha classe fornecedor tinha chave primaria e a chave estrangeira, bom não sei sé isso mesmo que você questionou.



Sim, foi exatamente isso. Você estava colocando a mesma propriedade como chave primária e estrangeira, ocasionando um conflito. Você já experimentou retirar essa propriedade [Ô]PessoaId[Ô] da classe Fornecedor, deixando só a que está na classe base EntityBase? Se não funcionar, coloque-o na classe Pessoa. Desta forma, você não precisará ficar colocando um identificador nas classes filhas toda vez que quiser criar uma nova. Se funcionar com uma dessas maneiras, retire também a propriedade [Ô]pessoa[Ô] da classe Fornecedor e faça o teste.
MRSILVA 20/10/2017 08:18:22
#477271
Jaba.

Não fiz o teste ainda, mais se tirar a [Ô]PessoaId[Ô] da classe Fornecedor como que o Entity vai saber que a classe fornecedor está relacionando com a classe Pessoa através da chave primaria (Id) da classe Pessoa? Acredito que se tirar [Ô]PessoaId[Ô] a tabela fornecedor não terá mais relacionamento, ou seja, preciso que cada registro da tabela fornecedor tenha um registro pai na da tabela Pessoa.

Assim puder vou fazer os testes que sugeriu.

obrigado!
JABA 20/10/2017 15:17:29
#477280
Citação:

Não fiz o teste ainda, mais se tirar a [Ô]PessoaId[Ô] da classe Fornecedor como que o Entity vai saber que a classe fornecedor está relacionando com a classe Pessoa através da chave primaria (Id) da classe Pessoa? Acredito que se tirar [Ô]PessoaId[Ô] a tabela fornecedor não terá mais relacionamento, ou seja, preciso que cada registro da tabela fornecedor tenha um registro pai na da tabela Pessoa.



www.dotnettricks.com/learn/entityframework/understanding-inheritance-in-entity-framework

O último exemplo do link acima é o mesmo caso do seu e mostra que não é necessário fazer isso.
MRSILVA 20/10/2017 16:14:46
#477281
Jabá.
Agora entendi, você tem razão, dessa forma vou ter um atributo a menos para preencher na minha classe fornecedor já que a ID das classes vinculadas serão as mesmas.

Muito obrigado!!!
Tópico encerrado , respostas não são mais permitidas