Error in 1 to 1 relationship declaration in EF with code-first and attributes!

3

I have the following classes where I want to do a 1 to 1 relationship:

User:

[Table("Usuario")]
public class Usuario
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [EmailAddress]
    [StringLength(150)]
    [DataType(DataType.EmailAddress)]
    [Index("unq_Usuario_Login", IsUnique = true)]
    public string Login { get; set; }

    [Required]
    [StringLength(30)]
    public string Nome { get; set; }

    [StringLength(50)]
    [DataType(DataType.Password)]
    public string Senha { get; set; }

    [InverseProperty("Usuario")]
    public virtual UsuarioConfiguracao Configuracoes { get; set; }

    [InverseProperty("Usuario")]
    public virtual ICollection<UsuarioDepartamento> Departamentos { get; set; }
}

User Settings:

[Table("UsuarioConfiguracao")]
public class UsuarioConfiguracao
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public int UsuarioId { get; set; }

    [ForeignKey("UsuarioId")]
    public virtual Usuario Usuario { get; set; }

    [Required, DefaultValue(false)]
    public bool EMailDeAtendimento { get; set; }

    [Required, DefaultValue(false)]
    public bool EMailDeArquivoPublicado { get; set; }

    [Required, DefaultValue(false)]
    public bool SmsDeAtendimento { get; set; }

    [Required, DefaultValue(false)]
    public bool SmsDeArquivoPublicado { get; set; }
    ...
}

When I run enable-migrations I get the following error message:

  

Unable to determine the principal end of an association between the types 'User.domain' and 'Domain.User.Configuration'. The main end of this association must be explicitly configured using either the fluent relationship API or data annotations ..

I think I've seen similar issues here in SOpt but I have not found it. And I would like to know how to resolve with Attributes and why does this occur?

Editing

By putting the Required attribute in the Configuracoes property of the Usuario class my error has changed:

[Required]
[InverseProperty("Usuario")]
public virtual UsuarioConfiguracao Configuracoes { get; set; }
  

The ForeignKeyAttribute on property 'User' on type 'Domain.UserConfiguration' is not valid. The foreign key name 'UserId' was not found on the dependent type 'Domain.Users'. The Name value should be the comma separated list of foreign key property names.

I found it strange but I changed it in my class UserConfiguration for:

[ForeignKey("Id")]
public virtual Usuario Usuario { get; set; }

And the addition of Migrations worked. Is it right? Because he did not accept UsuarioId ? Should not be the property of the class itself in which the attribute is, which in this case would refer to Key of the referenced class?

    
asked by anonymous 01.07.2014 / 16:38

1 answer

4

1 to 1

If you use the 1 to 1 rule in EntityFramework it would look something like this:

[Table("Usuario")]
public class Usuario
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [EmailAddress]
    [StringLength(150)]
    [DataType(DataType.EmailAddress)]
    [Index("unq_Usuario_Login", IsUnique = true)]
    public string Login { get; set; }

    [Required]
    [StringLength(30)]
    public string Nome { get; set; }

    [StringLength(50)]
    [DataType(DataType.Password)]
    public string Senha { get; set; }

    [InverseProperty("Usuario")]
    public virtual UsuarioConfiguracao Configuracoes { get; set; }

    [InverseProperty("Usuario")]
    public virtual ICollection<UsuarioDepartamento> Departamentos { get; set; }
}


[Table("UsuarioConfiguracao")]
public class UsuarioConfiguracao: Usuario
{           
    [Required, DefaultValue(false)]
    public bool EMailDeAtendimento { get; set; }

    [Required, DefaultValue(false)]
    public bool EMailDeArquivoPublicado { get; set; }

    [Required, DefaultValue(false)]
    public bool SmsDeAtendimento { get; set; }

    [Required, DefaultValue(false)]
    public bool SmsDeArquivoPublicado { get; set; }
    ...
}

That is, in general terms it is called Herança

I did not check all your fields, I just put the original form from 1 to 1     
01.07.2014 / 16:43