none
Problema com classe RRS feed

  • Pergunta

  • Bom dia, estou tentando adicionar uma propriedade dentro de uma classe que referencie outra classe, para pegar os atributos da classe.
    Exemplificando:

    Tenho minha classe "USUARIO", que tem a propriedade "NOME". Tenho minha classe "EPIGrupo", e lá tem "UsuCad", que seria o vinculo entre a tabela "USUARIO.UsuarioID" e o campo "UsuCad". Na classe "EPIGrupo", queria ter a propriedade como abaixo:

    public virtual Usuario UsuarioCad { get; set; }

    Já tentei de várias maneiras e nada. As classes estão abaixo. Lembrando que estou usando EF e CF. E o erro que está dando agora tá lá em baixo.

    EPIGrupo.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.ModelConfiguration.Conventions;
    using System.Web.Mvc;
    using ERP.Interface;
    
    namespace ERP.Models
    {
        public class EPIGrupo : IEntidadeBase
        {
            [Key]
            public int GrupoID { get; set; }
    
            [Required(ErrorMessage = "Obrigatório")]
            [Display(Name = "Sigla")]
            [MaxLength(5)]
            public string Sigla { get; set; }
    
            [Required(ErrorMessage = "Obrigatório")]
            [Display(Name = "Descrição")]
            [MaxLength(250)]
            public string Descricao     { get; set; }        
    
            public int EmpresaID        { get; set; }
    
            public string Fixo          { get; set; }
            public string Status        { get; set; }        
    
            public string Apagado       { get; set; }
            public DateTime? DtApagado   { get; set; }
                    
            public int UsuCad { get; set; }
            
            public DateTime DtCad { get; set; }
    
            
            public int UsuAlt { get; set; }
            public DateTime DtAlt { get; set; }
    
            public int UsuUltAlt { get; set; }
            public DateTime DtUltAlt { get; set; }
    
            [ForeignKey("Usuario")]        
            public virtual Usuario UsuarioCad { get; set; }
       
        }
    }


    Usuario.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.ModelConfiguration.Conventions;
    using System.Web.Mvc;
    using ERP.Helpers;
    using ERP.Interface;
    
    namespace ERP.Models
    {
    
        public class UsuarioConectar
        {
            [Required(ErrorMessage = "Obrigatório")]
            [Display(Name = "Login no sistema")]
            //[CustomValidation(typeof(Validacoes), "Email")]
            [ERP.Helpers.Validacoes.Email]
            public string Login { get; set; }
    
            [Required(ErrorMessage = "Obrigatório")]
            [DataType(DataType.Password)]
            [Display(Name = "Digite a senha")]        
            public string Senha { get; set; }
        }
    
        public class Usuario
        {
            [Key]
            public int UsuarioID { get; set; }
    
            [Required(ErrorMessage = "Campo 'E-mail (Login)' é obrigatório")]
            [Display(Name = "E-mail (Login)")]        
            [DataType(DataType.EmailAddress)]
            [ERP.Helpers.Validacoes.Email]
            public string Email { get; set; }
    
            [Required(ErrorMessage = "Campo 'Nome' é obrigatório")]
            [Display(Name = "Nome")]
            public string Nome { get; set; }
    
            [Required(ErrorMessage = "Campo 'Senha' é obrigatório")]
            [Display(Name = "Senha")]
            [StringLength(50, ErrorMessage = "A {0} deve ter {2} caracteres no mínimo", MinimumLength = 6)]
            [DataType(DataType.Password)]        
            public string Senha { get; set; }
    
            [Required(ErrorMessage = "Campo 'Confirme a senha' é obrigatório")]        
            [Display(Name = "Confirme a senha")]
            [Compare("Senha", ErrorMessage = "A 'senha' e a 'confirme a senha' não estão iguais")]
            [DataType(DataType.Password)]
            [NotMapped]
            public string ConfirmeSenha { get; set; }
    
            public string Perfil { get; set; }         
            public string Chave { get; set; }
            public Nullable<DateTime> DtAtivacao { get; set; }
    
            [Required(ErrorMessage = "Campo 'Tipo de pessoa' é obrigatório")]
            [Display(Name = "Tipo de pessoa")]
            public int TipoPessoaID { get; set; }
    
            [Required(ErrorMessage = "Campo 'Sexo' é obrigatório")]
            [Display(Name = "Sexo")]
            [ERP.Helpers.Validacoes.CompareValuesAttribute("TipoPessoaID")]
            public int SexoID { get; set; }
    
            public int EmpresaID { get; set; }
            public string Fixo { get; set; }
            public string Status { get; set; }
            public string Apagado { get; set; }
            public Nullable<DateTime> DtApagado { get; set; }
            public int UsuCad { get; set; }
            public DateTime DtCad { get; set; }
            public int UsuAlt { get; set; }
            public DateTime DtAlt { get; set; }
            public int UsuUltAlt { get; set; }
            public DateTime DtUltAlt { get; set; }
        }    
    
    }
    


    E o DbContext é:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    using ERP.Models.Basicas;
    using ERP.Helpers;
    
    
    namespace ERP.Models
    {
        public class ERPCodeFirstContext : DbContext
        {
            public DbSet<Usuario> Usuario { get; set; }
            public DbSet<Empresa> Empresa { get; set; }
            
            public DbSet<CNAES> CNAES { get; set; }                
            public DbSet<EPIGrupo> EPIGrupo { get; set; }
            public DbSet<Sexo> Sexo { get; set; }
            public DbSet<TipoPessoa> TipoPessoa { get; set; }
    
    
            public ERPCodeFirstContext()
            {
                Database.SetInitializer<ERPCodeFirstContext>(null);            
            }       
    		
    		protected override void OnModelCreating(DbModelBuilder modelBuilder)
    		{
                var _DBOwner = "dbo";
    
                modelBuilder.Entity<Usuario>().ToTable("Usuario", schemaName: _DBOwner);
                modelBuilder.Entity<Empresa>().ToTable("Empresa", schemaName: _DBOwner);
    
                modelBuilder.Entity<CNAES>().ToTable("CNAES", schemaName: _DBOwner);
    
                modelBuilder.Entity<EPIGrupo>().ToTable("EPIGrupo", schemaName: _DBOwner);
                modelBuilder.Entity<Sexo>().ToTable("Sexo", schemaName: _DBOwner);
                modelBuilder.Entity<TipoPessoa>().ToTable("TipoPessoa", schemaName: _DBOwner);            
    		}
    	}
    }

    O erro que aprece é:

    Server Error in '/' Application.

    The ForeignKeyAttribute on property 'UsuarioCad' on type 'ERP.Models.EPIGrupo' is not valid. The foreign key name 'Usuario' was not found on the dependent type 'ERP.Models.EPIGrupo'. The Name value should be a comma separated list of foreign key property names.



    Abs




    Marlon Tiedt
    www.sesmt.com.br

    quinta-feira, 28 de junho de 2012 12:11

Respostas

Todas as Respostas

  • Opa, vê esse post aqui

    http://stackoverflow.com/questions/5542864/how-should-i-declare-foreign-key-relationships-using-code-first-entity-framework

    Ele relata sobre o seu problema de mapear as properties com nomes diferentes


    Não esqueça de marcar o post como útil caso tenha te ajudado.

    quinta-feira, 28 de junho de 2012 12:54
  • Olá Marlon,

    Ao invés de

    [ForeignKey("Usuario")]  

    Faça

    [ForeignKey("UsuCad")]  

    []s!

    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    • Sugerido como Resposta Latino terça-feira, 10 de julho de 2012 21:09
    • Marcado como Resposta Marlon Tiedt segunda-feira, 23 de julho de 2012 14:07
    quinta-feira, 28 de junho de 2012 13:32
    Moderador
  • Valeu pessoal, funcionou.

    Agora gostaria de entender uma coisa.
    Se eu pegar a propriedade:

    public int UsuCad { get; set; }


    em vez de colocar ela como "int" eu colocar ela como "Usuario", quando for executar um db.SaveChanges(); o EF vai validar se existe um usuário para o UsuarioID informado no UsuCad?

    Como eu deveria proceder para a ForeignKey do UsuCad se ele for da classe "Usuario"?

    Fernando, você teria alguma referencia legal para estudar estes detalhes?

    Abs


    Marlon Tiedt
    www.sesmt.com.br

    quinta-feira, 28 de junho de 2012 13:52
  • Olá Marlon,

    No caso, vc já tem a propriedade UsuarioCad e mudar o tipo de dados da propriedade UsuCad para o tipo de dados Usuario vai ficar redundante. Mas, mesmo assim, se vc mudar o tipo de dados para uma instância, e o EntityState (estado da entidade controlado pelo Entity Framework) dessa instância estiver como Added, então o usuário será inserido na base de dados, senão não.

    O campo da Foreign Key não precisa existir na sua classe, por convenção, o Entity Framework irá criar um campo de nome UsuCadId na sua tabela e irá associar a Foreign Key a este campo automaticamente.

    Existem alguns livros que eu comentei nesta thread que são bastante interessantes: http://social.msdn.microsoft.com/Forums/pt-BR/adoptpt/thread/49983a46-1acb-45ad-b68d-d7936dc7585b

    Eu já li todos estes livros e recomendo a todos.

    Quero aproveitar esse mês para fazer um post sobre o mapeamento de relacionamentos. É algo muito discutido na comunidade e não existe nenhum post sobre o assunto...

    O que precisar é só falar.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    quinta-feira, 28 de junho de 2012 17:16
    Moderador
  • E ai Fernando, queria fazer somente para testar ou melhor, para ter somente o atribuito UsuCad. Porém quando tentei fazer deu o erro abaixo. 
    Vou ficar no aguardo do seu post, mas não esqueça que este mês tem somente mais 2 dias, ou seja você precisa fazer até sábado a noite... :)...Brincadeira...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.ModelConfiguration.Conventions;
    using System.Web.Mvc;
    using ERP.Interface;
    
    namespace ERP.Models
    {
        public class EPIGrupo : IEntidadeBase
        {
            [Key]
            public int GrupoID { get; set; }
    
            [Required(ErrorMessage = "Obrigatório")]
            [Display(Name = "Sigla")]
            [MaxLength(5)]
            public string Sigla { get; set; }
    
            [Required(ErrorMessage = "Obrigatório")]
            [Display(Name = "Descrição")]
            [MaxLength(250)]
            public string Descricao     { get; set; }        
    
            public int EmpresaID        { get; set; }
    
            public string Fixo          { get; set; }
            public string Status        { get; set; }        
    
            public string Apagado       { get; set; }
            public DateTime? DtApagado   { get; set; }
            
            [ForeignKey("UsuarioID")]
            public Usuario UsuCad { get; set; }
            
            public DateTime DtCad { get; set; }
    
            
            public int UsuAlt { get; set; }
            public DateTime DtAlt { get; set; }
    
            public int UsuUltAlt { get; set; }
            public DateTime DtUltAlt { get; set; }
    
            [ForeignKey("UsuCad")]
            public virtual Usuario UsuarioCad { get; set; }
            [ForeignKey("UsuAlt")]
            public virtual Usuario UsuarioAlt { get; set; }
            [ForeignKey("UsuUltAlt")]
            public virtual Usuario UsuarioUltAlt { get; set; }
       
        }
    }
    Erro que dá:

    Server Error in '/' Application.

    The ForeignKeyAttribute on property 'UsuCad' on type 'ERP.Models.EPIGrupo' is not valid. The foreign key name 'UsuarioID' was not found on the dependent type 'ERP.Models.EPIGrupo'. The Name value should be a comma separated list of foreign key property names.



    Abs


    Marlon Tiedt
    www.sesmt.com.br

    sexta-feira, 29 de junho de 2012 01:26
  • Olá Marlon!

    Tudo beleza? :) Espero que sim...

    Quando vc utiliza o atributo ForeignKey vc esta informando ao EF que ele deve se basear na Propriedade X da sua classe (no caso, aquela que foi informada no atributo ForeignKey) que ela detem as informações da Foreign Key. Quando vc não estipula isso, o EF faz uso de suas convenções e irá procurar por um campo que seja o nome do tipo de dados mais a palavra ID, por esse motivo o erro fala sobre a coluna "UsuarioID".

    No caso, acredito eu, que para tudo funcionar corretamente vc deve alterar no seu banco de dados o nome de sua coluna para "UsuarioID" e remover aquele campo de tipo INT que vc tem na sua classe para fazer papel de Foreign Key.

    ps.: hehehe me expressei mal! na verdade seria "dentro dos próximos 30 dias" :)

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    sexta-feira, 29 de junho de 2012 02:10
    Moderador
  • Olá Fernando!

    Tudo tranquilo comigo e com você?

    Entendi o que você falou, porém então no meu caso vou ter que deixar da forma que está..Utilizando Virtual mesmo. Pois na minha classe eu tenho 3 FKs com USUARIO. UsuCad, UsuAlt, UsuUltAlt.

    Abs


    Marlon Tiedt
    www.sesmt.com.br

    sexta-feira, 29 de junho de 2012 02:26
  • Olá Marlon,

    Podemos fechar esta thread?

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil

    terça-feira, 10 de julho de 2012 21:13
    Moderador