Pregunta

I'm using the Code First approach to build the database in this problem. I have the following (partial) entity:

public class Tournament {
    public int TournamentID { get; set; }
    public String Name { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public int? SportID { get; set; }

    public virtual Sport Sport { get; set; }

    public virtual ICollection<Official> Officials { get; set; }
}

In the Official Entity I have this:

public class Official {
    public int OfficialID { get; set; }
    public String Surname { get; set; }
    public String FirstName { get; set; }
    public int? TournamentID { get; set; }

    public virtual Tournament Tournament { get; set; }

    public virtual ICollection<Match> Matches { get; set; }
}

Using some sample data and checking the SQL Server database, this works as I would expect it to. The tournament has a one-to-many relationship with officials.

The problem I'm having is that I would like the tournament to hold the primary key of an official as the head official. So I would add to the Tournament entity:

public int? OfficialID { get; set; } // foreign key to official table
public virtual Official HeadOfficial { get; set; } // navigation property

If I do this I get an attribute OfficialID and HeadOfficial_OfficialID in my Tournament table and I get TournamentID, Tournament_TournamentID and Tournament_TournamentID1 in my Officials table. I realise I now not only have a one-to-many relationship between Tournament and Official (seeing as a tournament can have many officials), but I also have a one-to-one relationship (seeing as a tournament can only have one head official).

How can I fix this problem?

¿Fue útil?

Solución

You can fix the problem by giving EF a hint which navigation properties belong together. EF conventions cannot decide this anymore when you have two navigation properties in a class which refer to the same target class:

public class Tournament {
    public int TournamentID { get; set; }
    //...

    public int? OfficialID { get; set; }
    [ForeignKey("OfficialID")]
    public virtual Official HeadOfficial { get; set; }

    [InverseProperty("Tournament")] // the navigation property in Official class
    public virtual ICollection<Official> Officials { get; set; }
}

It's also possible with Fluent API if you prefer that:

modelBuilder.Entity<Tournament>()
    .HasOptional(t => t.HeadOfficial)
    .WithMany()
    .HasForeignKey(t => t.OfficialID);

modelBuilder.Entity<Tournament>()
    .HasMany(t => t.Officials)
    .WithOptional(o => o.Tournament)
    .HasForeignKey(o => o.TournamentID);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top