【问题标题】:Use navigation properties more than once C# EF Core多次使用导航属性 C# EF Core
【发布时间】:2022-01-01 09:34:40
【问题描述】:

我有这个数据库结构

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; }

}

这就是我创建关系的方式:

  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);

我收到此错误:

无法在“Gameboard.Colors”和“ColorGameBoard.Gameboard”之间创建关系,因为“Gameboard.CorrectColors”和“ColorGameBoard.Gameboard”之间已经存在关系。导航属性只能参与单个关系。如果您想在“OnModelCreating”中首先在导航“ColorGameBoard.Gameboard”上覆盖现有关系调用“Ignore”。

数据库结构:在 Gameboard 上有两个带颜色的列表。每个列表应包含至少 5 种颜色。并且数据库中的每种颜色都可以在多个游戏板上使用。此外,一种颜色可以在游戏板上多次使用。

有人知道如何解决这个错误吗?

【问题讨论】:

  • 您需要两个联结类,ColorGameBoardCorrectColorGameBoard

标签: c# asp.net asp.net-core entity-framework-core ef-core-2.0


【解决方案1】:

您的代码中存在一些对比关系问题。 Gameboard 类中有两个ICollection&lt;ColorGameBoard&gt;,但ColorGameBoard 类中只有一个 Gameboard。这样,在构建数据库的时候就会出错。比较关系的数量应该是一致的。在 EF Core 中构建 InverseProperty 属性时,可以使用一些属性,例如:virtual,ForeignKey,InverseProperty

不知道你对数据库的需求是什么,所以我写了两个demo,下面是我的代码:

第一个demo,两个class Gameboard对应一个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; }

    }

颜色类

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.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); 

然后,就可以创建数据库了

第二个demo,一个class Gameboard对应两个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; }
        
    }

颜色类

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.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);

然后,您可以创建数据库

【讨论】:

  • 当我想向游戏板添加颜色列表时该怎么办?我现在有这个代码: var gameboard = new Gameboard() { Id = GenerateRandomId(), Colors = db.GameboardColors.Where(x => x.GameBoardId == id).ToList(), MaxTries = numberOfGuesses, Round = 1 , };
  • @raj 我非常怀疑这两种设计的正确性。正如我上面所说,我认为您只需要两个连接类,因此您可以独立处理颜色列表。
猜你喜欢
  • 1970-01-01
  • 2018-05-09
  • 2018-10-22
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
相关资源
最近更新 更多