简体   繁体   中英

How to create two navigation properties to one model (EF6 Code First)

Using EF6 Code First convention, I want to create model with two foreign keys to the same table. For instance, now I have Team model:

public class Team
{
    public Guid Id { get; set; }
    public String Name { get; set; }

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

and Match model:

public class Match
{
    public Guid Id { get; set; }
    public Int32 TeamHomeScore { get; set; }
    public Int32 TeamAwayScore { get; set; }

    public Guid TeamHomeId { get; set; } // I want these properties to be foreign keys
    public Guid TeamAwayId { get; set; } //

    public virtual Team TeamHome { get; set; }
    public virtual Team TeamAway { get; set; }
}

But after project running I've got next exception:

Introducing FOREIGN KEY constraint 'FK_dbo.Matches_dbo.Teams_TeamHomeId' on table 'Matches' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint.

Any recommendations ?

try this, if you use migrations. Migrations are not smart everytime, you should interreput the code sometimes.

public class Match
{
    public Guid Id { get; set; }
    public Int32 TeamHomeScore { get; set; }
    public Int32 TeamAwayScore { get; set; }

    public Guid TeamHomeId { get; set; } // I want these properties to be foreign keys
    public Guid TeamAwayId { get; set; } //

    [ForeginKey("TeamHomeId")]
    public virtual Team TeamHome { get; set; }
    [ForeginKey("TeamAwayId")]
    public virtual Team TeamAway { get; set; }
}

and then you will add below to your DataContex.cs

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
modelBuilder.Entity<Match>()
               .HasRequired(a => a.TeamHome )
               .WithMany()
               .HasForeignKey(u => u.TeamHomeId);

modelBuilder.Entity<Match>()
               .HasRequired(a => a.TeamAway )
               .WithMany()
               .HasForeignKey(u => u.TeamAwayId);
}

SQL Server is returning an error because it can't handle multiple cascade paths. The multiple path is the Match having many Team properties.

Set cascade on delete to false.

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Match>()
                    .HasRequired<Team>(i => i.TeamHome)
                    .WithMany(i => i.Matches)
                    .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

Since there is no cascade delete, you must delete the team's matches first before deleting the team itself.

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