2

1) I am trying to establish a relationship between two classes. So, I have the following class

 public class Team
{
    [Key]        
    public int Id { get; set; }

    public string Team { get; set; }

    public List<MatchGame> MatchGames { get; set; }
}

and

public class MatchGame
{
    [Key]
    public int Id { get; set; }

    public int HomeTeamId { get; set; }
    public Team HomeTeam { get; set; }
   
    public int AwayTeamId { get; set; }
    public Team AwayTeam { get; set; }

}

The configuration that I tried to perform the relashioship is

   protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder.Entity<MatchGame>()
            .HasOne(h => h.HomeTeam)
            .WithMany(m => m.MatchGames)
            .HasForeignKey(k => k.HomeTeamId)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<MatchGame>()
            .HasOne(h => h.AwayTeam)
            .WithMany(m => m.MatchGames)
            .HasForeignKey(k => k.AwayTeamId)
            .OnDelete(DeleteBehavior.NoAction);
    }

the produced error is:

Cannot create a relationship between 'Team.MatchGames' and 'MatchGame.AwayTeam' because a relationship already exists between 'Team.MatchGames' and 'MatchGame.HomeTeam'. Navigation properties can only participate in a single relationship. If you want to override an existing relationship call 'Ignore' on the navigation 'MatchGame.AwayTeam' first in 'OnModelCreating'.

I have also seen the following threads but couldn't find the reason why the relationship couldn't establish.

EF code first: one-to-many twice to same collection type

https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/fluent/relationships

EFCore - How to have multiple navigation properties to the same type?

2) Also, in order not to create a new post: I wanted to have the public string Team { get; set; } in the Team Class to be Unique. I tried some DataAnnotation that I have seen but didn't work. what do I have to use for this purpose.

fl1
  • 66
  • 7
  • @philipxy the post seems to be clear and explanatory showing the appropriate research – noruk Mar 10 '21 at 13:51
  • my mistake would be that I also asked for another question but I thought it would be not that big deal as it is seeks to find just a data annotation. My intention was not to create a new post for just a data annotation – fl1 Mar 10 '21 at 14:14

1 Answers1

1

The problem is you try to use one navigation property MatchGames for defining relationship. Try create two separate navigation properties like below.

public class Team
{
    public int Id { get; set; }
    public string TeamName { get; set; }
    public List<Match> HomeMatches { get; set; }
    public List<Match> AwayMatches { get; set; }
}

public class MatchGame
{
    public int Id { get; set; }
    public int HomeTeamId { get; set; }
    public Team HomeTeam { get; set; }
    public int AwayTeamId { get; set; }
    public Team AwayTeam { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MatchGame>(entity =>
    {
        entity.HasOne(m => m.HomeTeam)
           .WithMany(t => t.HomeMatches)
           .HasForeignKey(m => m.HomeTeamId)
           .IsRequired()
           .OnDelete(DeleteBehavior.Cascade);

        entity.HasOne(m => m.AwayTeam)
           .WithMany(t => t.AwayMatches)
           .HasForeignKey(m => m.AwayTeamId)
           .IsRequired()
           .OnDelete(DeleteBehavior.Cascade);
    });

}

Ad 2. You need to create unique index on TeamName:

modelBuilder.Entity<Team>(e => e.HasIndex(t => t.TeamName).IsUnique());

Also you can consider to add MaxLength attributes in your model and so on.

axelio
  • 159
  • 4
  • Thank you for the answer. I modified the second `.OnDelete(DeleteBehavior.Cascade);` to ActionNone as it couldn't create the table. it didn't accept two `.OnDelete(DeleteBehavior.Cascade);` Produced Error Number:1785,State:0,Class:16 Introducing FOREIGN KEY constraint 'FK_MatchGames_Teams_HomeTeamId' on table 'MatchGames' 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 or index. See previous errors. – fl1 Mar 13 '21 at 14:02
  • By the way, I can not understand why the way I tried to make the relationship with one navigation property didn't work. I had implemented it the same way in .Net Framework 4.7 and I tried it to .net core 5. Plus the threads that I submitted by creating this thread, present the way I tried to implement. _Why in other similar situations worked with one navigation property?_ – fl1 Mar 13 '21 at 14:03
  • 1
    The way I understand it is because having one navigation property for two foreign keys it would not be possible for Entity Framework to understand which data from foreign key to load. – axelio Mar 14 '21 at 15:39