Error in relation statement 1 to 1 in EF with code-first and attributes!

Asked

Viewed 383 times

3

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

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 rotating the enable-migrations get the following error message:

Unable to determine the main end of an Association between the types 'Domain.User' and 'Domain.User configuration'. The main end of this Association must be explicitly configured using either the Relationship Fluent API or data Annotations..

I think I’ve seen similar questions here at Sopt but I haven’t found.
And I’d like to know how to deal with Attributes and why this occurs?


Editing

When placing the attribute Required on the property Configuracoes class Usuario my mistake has changed:

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

The Foreignkeyattribute on Property 'Usuario' on type 'Domain.Usuarioconfiguracao' is not Valid. The Foreign key name 'Usuarioid' was not found on the dependent type 'Dominio.Usuario'. The Name value should be a comma separated list of Foreign key Property Names.

I found it strange but changed in my User class:

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

And it worked the addition of Migrations. Is that right? Because he didn’t accept the UsuarioId? It should not be the property of the class in which the attribute is itself, which in this case would refer to Key of the class referred to in?

  • 1

    Dude, I don’t think you need to declare the User twice like you’re doing... take that User Foreignkey note to see if it works. Maybe that’s what.

  • That solved your problem ?

  • 1

    Because this Id you are pulling as a foreign key is from your User table and not from the User table configuration, that is, the concept of inheritance of the answer below. Got it ?

  • 1

    Calm man. Needing we are there !

1 answer

4

1 to 1

If you use rule 1 to 1, no Entityframework would be more or less 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

Obs: I didn’t check all your fields, I just put the original form from 1 to 1

  • Of course you would! is inherited from the User class.

  • 1

    This... you will have to use technique with Oftype and various tricks to work, I already use in a project and became very cool!!! is well organized!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.