【发布时间】:2021-08-22 08:14:48
【问题描述】:
我正在尝试在 EFCore 中配置与实体之间的关系:Square 和 Position。 Position 与名为squares 的正方形之间存在一对(位置)对多(正方形)关系,在名为enPassentTakablePawnOfWhite 的Square 和enPassentTakablePawnOfBlack 之间存在两个一对一关系。请注意,两个实体中的 FK 和 PK 都是影子属性:
public class PositionTypeConfiguration : IEntityTypeConfiguration<Position>
{
public void Configure(EntityTypeBuilder<Position> builder)
{
builder.ToTable("Positions");
builder.Property<Guid>("BoardId");
builder.Property<Guid?>("CurrentPositionId");
builder.HasOne<Board>().WithMany("previosPositions").HasForeignKey("BoardId");
builder.HasOne<Board>().WithOne("currentPosition").IsRequired(false).HasForeignKey<Position>("CurrentPositionId");
builder.HasMany<Square>("squares").WithOne().HasForeignKey("PositionId");
builder.Property<Guid?>("EnPassentTakableWhitePawnId");
builder.Property<Guid?>("EnPassentTakableBlackPawnId");
builder.HasOne<Square?>("enPassentTakablePawnOfWhite").WithOne().HasForeignKey<Position>("EnPassentTakableWhitePawnId");
builder.HasOne<Square?>("enPassentTakablePawnOfBlack").WithOne().HasForeignKey<Position>("EnPassentTakableBlackPawnId");
builder.Property("canWhiteCastleKingSide");
builder.Property("canWhiteCastleQueenSide");
builder.Property("canBlackCastleKingSide");
builder.Property("canBlackCastleQueenSide");
builder.Property("_50MovesRuleCounter");
builder.Property<Guid>("Id").ValueGeneratedOnAdd();
builder.HasKey("Id");
}
}
public class SqaureTypeConfiguration : IEntityTypeConfiguration<Square>
{
public void Configure(EntityTypeBuilder<Square> builder)
{
builder.ToTable("Sqaures");
builder.Property(s => s.File);
builder.Property<Guid>("PositionId");
builder.Property(s => s.Row);
//this is FK to some other, irrelavant entity.
builder.HasOne(s => s.Occupier).WithOne().IsRequired(false).HasForeignKey<Square>("OccupierId").IsRequired(false);
builder.Property<Guid>("Id");
builder.HasKey("Id");
builder.Property<Guid?>("OccupierId").IsRequired(false);
}
}
问题是,在生成迁移时,迁移在Square 中为Position 创建了以下两个FK:
public partial class ChangedBoard : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
/...
migrationBuilder.AddColumn<Guid>(
name: "PositionId1",
table: "Sqaures",
type: "uniqueidentifier",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Sqaures_PositionId1",
table: "Sqaures",
column: "PositionId1");
migrationBuilder.AddForeignKey(
name: "FK_Sqaures_Positions_PositionId1",
table: "Sqaures",
column: "PositionId1",
principalTable: "Positions",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
//there is also ```"PositionId" in other migration
我建议改为查看此图片,因为它更能说明问题:
平方表:
位置表:
如您所见,PositionId1、PositionId 和 BoardId 都在其中,即使他们没有。 (只有PositionId 应该存在,作为一对多关系的一部分)
这引起了一些实际问题,因为在使用 EFCore 重试Position 实体时,我得到所有平方重复(两次)
这是为什么呢?我该如何解决?我尝试将显式类型和 FK 名称添加到一对多关系,更改配置顺序等。没有任何效果。
以下是实体:
正方形:
public record Square(Piece? Occupier, int Row, int File) : IComparable<Square>
{
private Square() : this(returnNull())
{
}
private static Piece returnNull()
{
return null;
}
public int Row
{
get; set;
} = Row;
public int File
{
get; set;
} = File;
public Square(Piece? occupier) : this(occupier, 0, 0)
{
this.Occupier = occupier;
}
public void SetLocation(int row, int file)
{
Row = row;
File = file;
}
public int CompareTo(Square? other)
{
if(other is null)
return 1;
int result = this.Row.CompareTo(other.Row);
if(result != 0)
return result;
return this.File.CompareTo(other.File);
}
}
职位:
public record Position
{
private List<Square> squares;
public List<Square> Squares
{
get
{
return squares;
}
}
private int At(int row, int file)
{
return row * 8 + file;
}
private bool canWhiteCastleKingSide;
private bool canWhiteCastleQueenSide;
private bool canBlackCastleKingSide;
private bool canBlackCastleQueenSide;
private Square? enPassentTakablePawnOfWhite;
private Square? enPassentTakablePawnOfBlack;
private const int RowAmount = 8;
private const int FileAmount = 8;
private int _50MovesRuleCounter;
private readonly IDictionary<PieceType, Func<int, int, IEnumerable<Ply>>> possibleMovesGenerationFunctionsDictinary;
//.....
编辑:当我尝试删除 Positions 和 squares 的整个类型配置(PK 配置除外)时,从正方形到位置的 FK 仍然存在(仅其中一个)
此外,当我尝试删除 Squares 公共属性时,在删除所有类型配置后,定位的 FK 确实消失了,但登机的 FK(根本没有被引用,也不应该被这里)仍然存在。将公共属性的名称从 Squares 更改为其他名称不会改变任何内容,我仍然需要这个属性,所以我不能删除它。将其标记为 [NoMapped] 会导致相同的结果
【问题讨论】:
标签: c# sql-server entity-framework-core key one-to-many