Home > Enterprise >  Use navigation properties more than once C# EF Core
Use navigation properties more than once C# EF Core

Time:11-25

I have this Database structure

public class Gameboard
{
    public string Id { get; set; }
    public int Round { get; set; }
    public int MaxTries { get; set; }
    public ICollection<ColorGameBoard> Colors { get; set; }
    public ICollection<ColorGameBoard> CorrectColors { get; set; }

}
public class Color
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<ColorGameBoard> ColorGameBoards { get; set; }

}
public class ColorGameBoard
{
    public int Id { get; set; }
    public int GameBoardId { get; set;}
    public Gameboard Gameboard { get; set; }
    public int CorrectColorId { get; set; }
    public Color CorrectColors { get; set; }
    public int ColorId { get; set; }
    public Color Color { get; set; }

}

This is how I create the relations:

  modelBuilder.Entity<ColorGameBoard>()
            .HasOne(x => x.Gameboard)
            .WithMany(x => x.CorrectColors)
            .HasForeignKey(x => x.CorrectColorId);

        modelBuilder.Entity<ColorGameBoard>()
          .HasOne(x => x.Gameboard)
          .WithMany(x => x.Colors)
          .HasForeignKey(x => x.ColorId);

        modelBuilder.Entity<ColorGameBoard>()
           .HasOne(x => x.Color)
           .WithMany(x => x.ColorGameBoards)
           .HasForeignKey(x => x.GameBoardId);

I get this error:

Cannot create a relationship between 'Gameboard.Colors' and 'ColorGameBoard.Gameboard' because a relationship already exists between 'Gameboard.CorrectColors' and 'ColorGameBoard.Gameboard'. Navigation properties can only participate in a single relationship. If you want to override an existing relationship call 'Ignore' on the navigation 'ColorGameBoard.Gameboard' first in 'OnModelCreating'.

Database structure: On Gameboard has two list with colors. Each list should contain at least 5 colors. And every color in the database can be used on several gameboard. Furthermore, a color can be used as many times a wanted on a gameboard.

Anyone know how to fix that error?

CodePudding user response:

There are some contrast relationship problems in your code. There are two ICollection<ColorGameBoard> in the Gameboard class, but only one Gameboard is included in the ColorGameBoard class. In this way, an error will occur when constructing the database. The number of comparison relationships should be consistent. When you build InverseProperty Attribute in EF Core , you can use some attributes like :virtual,ForeignKey,InverseProperty.

I don't know what your needs for the database are,SO I write two demos,Here is my code:

The first demo,Two class Gameboard corresponds to one class Color.

Gameboard.class

public class Gameboard
    {
        public int Id { get; set; }
        public int Round { get; set; }
        public int MaxTries { get; set; }

        [InverseProperty("GameboardOne")]
        public ICollection<ColorGameBoard> OneBorad { get; set; }

        [InverseProperty("GameboardTwo")]
        public ICollection<ColorGameBoard> TwoBoard { get; set; }

    }

Color.class

public class Color
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [InverseProperty("Color")]
        public ICollection<ColorGameBoard> ColorGameBoards { get; set; }
    }

ColorGameBoard.class

public class ColorGameBoard
    {
        public int Id { get; set; }

        [ForeignKey("GameboardOne")]
        public int OneId { get; set; }
        public virtual Gameboard GameboardOne { get; set; }

        [ForeignKey("GameboardTwo")]
        public int TwoId { get; set; }
        public virtual Gameboard GameboardTwo { get; set; }

        [ForeignKey("Color")]
        public int ColorId { get; set; }
        public virtual Color Color { get; set; }
    }

modelBuilder

            modelBuilder.Entity<ColorGameBoard>()
                .HasOne(c => c.Color)
                .WithMany(a =>a.ColorGameBoards)
                .HasForeignKey(b => b.ColorId)
                .OnDelete(DeleteBehavior.NoAction);

            modelBuilder.Entity<ColorGameBoard>()
                .HasOne(d => d.GameboardOne)
                .WithMany(e => e.OneBorad)
                .HasForeignKey(b => b.OneId)
                .OnDelete(DeleteBehavior.NoAction); 

            modelBuilder.Entity<ColorGameBoard>()
                .HasOne(d => d.GameboardTwo)
                .WithMany(e => e.TwoBoard)
                .HasForeignKey(b => b.TwoId)
                .OnDelete(DeleteBehavior.NoAction); 

Then,You can create the database

enter image description here

The second demo,One class Gameboard corresponds to two class Color.

Gameboard.class

public class Gameboard
    {
        public int Id { get; set; }
        public int Round { get; set; }
        public int MaxTries { get; set; }
        [InverseProperty("Gameboard")]
        public ICollection<ColorGameBoard> Colors { get; set; }
        
    }

Color.class

public class Color
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [InverseProperty("Color")]
        public ICollection<ColorGameBoard> ColorGameBoards { get; set; }
        [InverseProperty("CorrectColors")]
        public ICollection<ColorGameBoard> CorrectColors { get; set; }
    }

ColorGameBoard.class

public class ColorGameBoard
    {
        public int Id { get; set; }

        [ForeignKey("Gameboard")]
        public int GameBoardId { get; set; }
        public virtual Gameboard Gameboard { get; set; }

        [ForeignKey("CorrectColors")]
        public int CorrectColorId { get; set; }
        public virtual Color CorrectColors { get; set; }

        [ForeignKey("Color")]
        public int ColorId { get; set; }
        public virtual Color Color { get; set; }
    }

modelBuilder

            modelBuilder.Entity<ColorGameBoard>()
                .HasOne(x => x.Gameboard)
                .WithMany(x => x.Colors)
                .HasForeignKey(x => x.GameBoardId)
                .OnDelete(DeleteBehavior.NoAction);

            modelBuilder.Entity<ColorGameBoard>()
              .HasOne(x => x.CorrectColors)
              .WithMany(x => x.CorrectColors)
              .HasForeignKey(x => x.CorrectColorId)
              .OnDelete(DeleteBehavior.NoAction);

            modelBuilder.Entity<ColorGameBoard>()
               .HasOne(x => x.Color)
               .WithMany(x => x.ColorGameBoards)
               .HasForeignKey(x => x.ColorId)
               .OnDelete(DeleteBehavior.NoAction);

Then, You can create the databse

enter image description here

  • Related