EF relationship

1

I know it's something basic, but how do I make a relationship between Entities using the Entity Framework?

I have the Contest table and the StatusContacts. The Contest table must have an associated status (Normal, Canceled and etc.).

Below is the class code:

[Table("Concursos")]
public class Concurso
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Id")]
    public int Id { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
    [Display(Name = "Descrição")]
    public string Descricao { get; set; }

    [Required]
    [DataType(DataType.DateTime, ErrorMessage = "A data de cadastro deve ser informada.")]
    [Display(Name = "Data Cadastro")]
    public DateTime DataCadastro { get; set; }

    [Required]
    [DataType(DataType.DateTime, ErrorMessage = "A data de início deve ser informada.")]
    [Display(Name = "Data Início")]
    public DateTime DataInicio { get; set; }

    [DataType(DataType.DateTime)]
    [Display(Name = "Data Fim")]
    public DateTime DataFim { get; set; }

    [Display(Name = "Observacao")]
    [StringLength(500, ErrorMessage = "The {0} deve ter no maximo {1} letras.")]
    public string Observacao { get; set; }

    public int? StatusID { get; set; }

    [ForeignKey("StatusID")]
    public virtual StatusConcursos StatusConcurso { get; set; }

}
public class StatusConcursos
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Id")]
    public int Id { get; set; }

    [Required]
    [Display(Name = "Descrição")]
    public string Descricao { get; set; }

    public virtual Concurso Concurso { get; set; }

}

The way this error occurs when trying to create a new migration. Here is the error message:

  

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

    
asked by anonymous 16.12.2016 / 19:49

2 answers

2

If it is 1 for muitos make the change in StatusConcursos that has a list of Concurso :

[Table("StatusConcursos")]
public class StatusConcursos
{
    public StatusConcursos()
    {
        Concursos = new HashSet<Concurso>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Id")]
    public int Id { get; set; }

    [Required]
    [Display(Name = "Descrição")]
    public string Descricao { get; set; }

    public virtual ICollection<Concurso> Concursos { get; set; }

}

Note: Concurso does not need any changes.

Useful reading:

16.12.2016 / 19:59
0

Well, first I'll show you a bit of how I usually do in my projects when I have the Status issue on certain features.

In order to perform the mapping in my projects, I define a history in the main entity, which in its case is Concurso . Staying as follows

    [Table("Concursos")]
    public class Concurso
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Display(Name = "Id")]
        public int Id { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
        [Display(Name = "Descrição")]
        public string Descricao { get; set; }

        [Required]
        [DataType(DataType.DateTime, ErrorMessage = "A data de cadastro deve ser informada.")]
        [Display(Name = "Data Cadastro")]
        public DateTime DataCadastro { get; set; }

        [Required]
        [DataType(DataType.DateTime, ErrorMessage = "A data de início deve ser informada.")]
        [Display(Name = "Data Início")]
        public DateTime DataInicio { get; set; }

        [DataType(DataType.DateTime)]
        [Display(Name = "Data Fim")]
        public DateTime DataFim { get; set; }

        [Display(Name = "Observacao")]
        [StringLength(500, ErrorMessage = "The {0} deve ter no maximo {1} letras.")]
        public string Observacao { get; set; }
        //histórico de status para o concurso
        public ICollection<ConcursoHistorico> ConcursosHistoricos { get; set; }    
    }

The second part is to define the ConcursoHistorico entity, being as follows

    [Table("ConcursosHistoricos")]
    public class ConcursoHistorico
    {
        public int ConcursoHistoricoId { get; set; }
        public ConcursoStatus Status { get; set; }
        public DateTime Data { get ;set; }
        public string Usuario { get; set; }
        public int ConcursoId { get; set; }
        public virtual Concurso Concurso { get; set; }
    }

I also have a Enum with possible status

public enum ConcursoStatus
    {
        Normal = 1,
        Cancelado = 2
    }

In this example I propose to you, it is defined that the mapping is from 1 to many, and a contest will always have several histories. Being the last entered history, the current status of the contest, you can do something like this to retrieve the current status

            using (TesteContext context = new TesteContext())
            {
                var concurso = context.Concursos.Include(a => a.ConcursosHistoricos).FirstOrDefault(a => a.Id == 1);

                var status = concurso.ConcursosHistoricos.OrderBy(a => a.Data).Last();
            }

See this link several examples mapping

    
16.12.2016 / 20:06