简体   繁体   中英

Too Many Foreign Keys in a One-to-Many

This problem is similar to:

Code First Multiple Foreign Keys for One to Many Relation

and

Entity Framework Code First - two Foreign Keys from same table

But not similar enough for me to gleen a solution.

I have a model "Team" that has one foreign key to another model called "Room" and a team can only have one room. The room model has two lists of Teams "p2teams" and "p3teams". In the teams table it is actually creating three different id columns to rooms: "RoomID", "Room_RoomID", and "Room_RoomID1".

This result in me trying to set a team's room (such as exampleTeam.Room = exampleRoom) and it only affects the RoomID column and not the rest. Furthermore, I just really don't fully get what is going on to have this result.

Below are my models, DB diagram, and some sample data from the team's table. Thanks for the help!

Team Model:

public class Team
{
    public int TeamID { get; set; }

    public int HighschoolID { get; set; }
    public virtual Highschool Highschool { get; set; }
    public int ContestID { get; set; }
    public virtual Contest Contest { get; set; }

    [ForeignKey("Room")]
    public int? RoomID { get; set; }
    public virtual Room Room { get; set; }

    public string Warning { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

Room Model:

public class Room
{
    public int RoomID { get; set; }

    public virtual ICollection<RoomUsage> RoomUsages { get; set; }

    public string Name { get; set; }

    public int? AvailibleSeats { get; set; }
    public int? TotalSeats { get; set; }

    public virtual ICollection<Student> p1Students { get; set; }
    public virtual ICollection<Team> p2Teams { get; set; }
    public virtual ICollection<Team> p3Teams { get; set; }
}

Relevant DB Diagram Image

First Few Rows of Teams Table

Once again, thanks for all your help.

Entity Framework is behaving properly. If you set a Teams Room property you are only affecting the RoomID in that table. The other columns are changed in the Rooms Table.

Your Rooms Table should only have one ICollection<Team> . If you want a Room to have multiple lists of teams add a TeamTypeID to the Teams table. A room can then have as many team lists as there are TeamTypes.

Because you have multiple ICollection<Team> in the Rooms table it is generating additional Columns in the Teams table.

Based on a lot of assumptions this is what I believe those two classes should look like

Team:

public class Team
{

    public int TeamID { get; set; }

    public int? RoomID { get; set; }

    public string Warning { get; set; }

    public virtual Room Room { get; set; }

    public virtual ICollection<Student> Students { get; set; }

    public virtual ICollection<Contest> Contests { get; set; }
}

Room:

public class Room
{
    public int RoomID { get; set; }

    public string Name { get; set; }

    public int? AvailableSeats { get; set; }

    public int? TotalSeats { get; set; }

    public virtual ICollection<Student> Students { get; set; }

    public virtual ICollection<Team> Teams { get; set; }

    public virtual ICollection<Usage> Usages { get; set; }
}

I have created a script that creates database tables with I believe will achieve your goals based on even more Assumptions:

• A student has
    One: Team, HighSchool, Room 
• A team has 
    One: Room
    Many: Contests 
• A room has 
    Many: Teams, Students, Usages 
• A contest has 
    Many: Teams 

If you still want to use code first you can use Entity Framework to generate Code First classes from these tables

create table dbo.HighSchools
(
    HighSchoolID int primary key,
    Name varchar(50)

)

create table dbo.Rooms
(
    RoomID int primary key,
    Name varchar(50),
    AvailableSeats int,
    TotalSeats int
)

create table dbo.Usages
(
    UsageID int primary key,
    Name varchar(50)
)

--If a Usage is Unique to each room I would remove this table and add RoomID to the Usages Table
create table dbo.RoomUsages
(
    UsageID int foreign key (UsageID) references Usages(UsageID),
    RoomID int foreign key (RoomID) references Rooms(RoomID),
    primary key (UsageID, RoomID)
)


create table dbo.TeamTypes
(
    TeamTypeID int primary key,
    Name varchar(50)
)

create table dbo.Teams
(
    TeamID int primary key,
    RoomID int foreign key (RoomID) references Rooms(RoomID),
    TeamTypeID int foreign key (TeamTypeID) references TeamTypes(TeamTypeID),
    Warning varchar(50)
)

--If a Student's room will always be the same as their Team's room I would remove the RoomID column from either Teams or Students 
create table dbo.Students
(
    StudentID int primary key,
    HighSchoolID int foreign key (HighSchoolID) references HighSchools(HighSchoolID),
    TeamID int foreign key (TeamID) references Teams(TeamID),
    RoomID int foreign key (RoomID) references Rooms(RoomID),
    Name varchar(50),
    DOB date,

)

create table dbo.Contests
(
    ContestID int primary key,
    Name varchar(50)
)

create table dbo.ContestTeams
(
    ContestID int foreign key (ContestID) references Contests(ContestID),
    TeamID int foreign key (TeamID) references Teams(TeamID),
    primary key (ContestID, TeamID)
)

DB Diagram

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM