Associação vários para 1 ( Csharp +(razor + asp.net mvc 3)

06/11/2012

0

Olá Pessoal

Tenho uma classe denominada de DadosPessoaJuridica, que tem uma associação de vários(*) para um(1) com a classe de Pessoa, veja:

    public class DadosPessoaJuridica
    {

        [Key]
        public int Id { get; set; }

        public string CNPJ { get; set; }

        public int? PessoaId { get; set; }
        public virtual Pessoa Pessoa { get; set; }
    }


    public class Pessoa
    {
        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "(Requerido)")]
        [DisplayName("Nome")]
        public string Nome { get; set; }

        public virtual DadosPessoaJuridica DadosPessoaJuridica { get; set; }
    }


O problema é que o .NET não está aceitando essa associação. O seguinte erro é emitido:


Unable to determine the principal end of an association between the types 'Sys.Models.PessoaJuridica' and 'Sys.Models.Pessoa'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.


Se algum colega puder me ajudar, ficarei muito grato.

Abraços
Hugo

Hugo

Responder

Posts

07/11/2012

Robson Alves


Quando preciso realizar este tipo de associação eu prefiro criar uma lista de objetos para gerar o relacionamento.

No caso:

    public class DadosPessoaJuridica
    {

        [Key]
        public int Id { get; set; }
        public string CNPJ { get; set; }
        public int? PessoaId { get; set; }
    }


    public class Pessoa
    {
        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "(Requerido)")]
        [DisplayName("Nome")]
        public string Nome { get; set; }

        public virtual IList<DadosPessoaJuridica> DadosPessoaJuridica { get; set; }
    }


Sendo sincero deve existir patterns ou melhores práticas para realizar este processo.

Eu também removeria o
public virtual Pessoa Pessoa { get; set; }


da classe DadosPessoaJuridica, assim ao acessar o objeto Pessoa, eu tenho a lista (*) dos dados jurídico dela;
Responder

07/11/2012

Hugo


Quando preciso realizar este tipo de associação eu prefiro criar uma lista de objetos para gerar o relacionamento.

No caso:

    public class DadosPessoaJuridica
    {

        [Key]
        public int Id { get; set; }
        public string CNPJ { get; set; }
        public int? PessoaId { get; set; }
    }


    public class Pessoa
    {
        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "(Requerido)")]
        [DisplayName("Nome")]
        public string Nome { get; set; }

        public virtual IList<DadosPessoaJuridica> DadosPessoaJuridica { get; set; }
    }


Sendo sincero deve existir patterns ou melhores práticas para realizar este processo.

Eu também removeria o
public virtual Pessoa Pessoa { get; set; }


da classe DadosPessoaJuridica, assim ao acessar o objeto Pessoa, eu tenho a lista (*) dos dados jurídico dela;


Bom dia Robson, obrigado pela resposta.

Eu tenho alguns questionamentos, são eles:

1º) No seu exemplo, você está sugerindo o uso de uma lista, então como ficaria o código abaixo no meu CONTROLLER de Pessoa para ler essa lista?

   var totalReg = _db.Pessoas.Where(filtro).Count();
   var data = _db.Pessoas.OrderBy(a => a.Nome).ToList();
   var registros = data.Select(x => new
            {
                x.Id,
                x.Nome,
                x.DadosPessoaJuridica.CNPJ
            });
            
   return Json(new
            {
                rows = registros,
                total = totalReg,
                success = true
            }, JsonRequestBehavior.AllowGet);


Te pergunto isso, porque na leitura acima, o .NET emitiu um erro:
System.NullRefenceException: Referência de objeto não definida para uma instância de um objeto.
. Acredito que isso ocorreu porque, por enquanto, o campo CNPJ
está nulo ou não existem dados na tabela. Então, como eu faço nessa situação?

2º) Procurando mais informações na documentação do .NET, a microsoft sugere que nestes casos deveríamos usar uma tal FLUENT API. Eu fiz assim e deu certo, mas gostaria de sua opinião Robson, até porque sou iniciante em .NET, veja:
            modelBuilder.Entity<Pessoa>()
            .HasOptional(b => b.DadosPessoaJuridica)
            .WithMany(a => a.PessoaId);
Responder

07/11/2012

Robson Alves


1) Te pergunto isso, porque na leitura acima, o .NET emitiu um erro:
System.NullRefenceException: Referência de objeto não definida para uma instância de um objeto.
. Acredito que isso ocorreu porque, por enquanto, o campo CNPJ
está nulo ou não existem dados na tabela. Então, como eu faço nessa situação?

2º) Procurando mais informações na documentação do .NET, a microsoft sugere que nestes casos deveríamos usar uma tal FLUENT API. Eu fiz assim e deu certo, mas gostaria de sua opinião Robson, até porque sou iniciante em .NET, veja:


Bem o primeiro erro aconteceu pq é necessário criar uma instância da lista. então:

    public class DadosPessoaJuridica
    {

        [Key]
        public int Id { get; set; }
        public string CNPJ { get; set; }
        public int? PessoaId { get; set; }
    }


    public class Pessoa
    {
        public Pessoa()
       {
        DadosPessoaJuridica = new IList<DadosPessoaJuridica>();
       }


        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "(Requerido)")]
        [DisplayName("Nome")]
        public string Nome { get; set; }

        public virtual IList<DadosPessoaJuridica> DadosPessoaJuridica { get; set; }
    }



O Fluent API eu não conheço, mas fiz umas pesquisas e entendi que é uma API (como o próprio nome traz) que utiliza as classes POCO (seu Model) de forma fácil utilizando métodos indicando o que você quer, ele é mais intuitivo para trabalhar. Tornando o código legível quanto as intenções.


É legal utilizar o fluentAPI, você vai ter uma curva de aprendizagem, entretanto estará utilizando uma estrutura que foi concebida por dois Ases do desenvolvimento: Eric Evans e Martin Fowler.
Responder

07/11/2012

Hugo

Muito obrigado pelas explicações Robson.

Forte abraço e Deus abencoe.
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar