Entity Framework Core 2 - 外键约束
Posted
技术标签:
【中文标题】Entity Framework Core 2 - 外键约束【英文标题】:Entity Framework Core 2 - Foreign Key Constraint 【发布时间】:2018-09-28 02:00:16 【问题描述】:我试图让一个模型有两个对另一个模型的引用。
我已经研究过这个错误,但看到了与以前的 .Net Core 版本相关的建议。
下面是模型
public class Match
public int ID get; set;
public DateTime MatchDateTime
get; set;
public int LocationID get; set;
public int GroupID get; set;
public int HomeTeamScore get; set;
public int AwayTeamScore get; set;
[Required]
public int HomeTeamID get; set;
public int AwayTeamID get; set;
public Location Location get; set;
public Group Group get; set;
[Required]
[ForeignKey("HomeTeamID")]
public Team HomeTeam get; set;
[ForeignKey("AwayTeamID")]
public Team AwayTeam get; set;
在运行迁移时,我收到此错误:
在表“Matches”上引入 FOREIGN KEY 约束“FK_Matches_Teams_AwayTeamID”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
【问题讨论】:
您能否向我们提供OnModelCreating
方法的内容(因为您使用的是 Code First 迁移)?我认为您在modelBuilder.Entity<Match>
关系中存在问题,可能会多次声明,导致多个循环或级联路径。
将你的 fk onelete 设置为限制而不是级联
该错误与任何 .Net 版本无关,它是一个 SQL Server 错误,很清楚地告诉您这是错误的。 Team
的两个 FK 不能都具有级联删除。
@TetsuyaYamamoto:我的 OnModelCreating() 函数中没有代码
@Mardoxx:我不确定我应该使用什么 DataAnnotation 来实现这一点。
【参考方案1】:
当你运行Add-Migration
时,它会生成类似下面代码的迁移文件。
migrationBuilder.CreateTable(
name: "Match",
columns: table => new
ID = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
AwayTeamID = table.Column<int>(nullable: false),
AwayTeamScore = table.Column<int>(nullable: false),
GroupID = table.Column<int>(nullable: false),
HomeTeamID = table.Column<int>(nullable: false),
HomeTeamScore = table.Column<int>(nullable: false),
LocationID = table.Column<int>(nullable: false),
MatchDateTime = table.Column<DateTime>(nullable: false)
,
constraints: table =>
table.PrimaryKey("PK_Match", x => x.ID);
table.ForeignKey(
name: "FK_Match_Team_AwayTeamID",
column: x => x.AwayTeamID,
principalTable: "Team",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Match_Team_HomeTeamID",
column: x => x.HomeTeamID,
principalTable: "Team",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
);
将ReferentialAction.NoAction
设置为FK_Match_Team_HomeTeamID
。
【讨论】:
【参考方案2】:所以..解决方案真的很简单。
我使外键 ID 可以为空。我不确定是否将两者都设为空是“必需的”
请看下面的代码:
public class Match
public int ID get; set;
public DateTime MatchDateTime
get; set;
public int LocationID get; set;
public int GroupID get; set;
public int HomeTeamScore get; set;
public int AwayTeamScore get; set;
public int? HomeTeamID get; set;
public int? AwayTeamID get; set;
public Location Location get; set;
public Group Group get; set;
[Required]
[ForeignKey("HomeTeamID")]
public Team HomeTeam get; set;
[ForeignKey("AwayTeamID")]
public Team AwayTeam get; set;
【讨论】:
如果你要求可以为空怎么办?以上是关于Entity Framework Core 2 - 外键约束的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core 2.1 中的 ReverseEngineeringGenerator
DetachedLazyLoadingWarning 的 Entity Framework Core 2.1 问题
Entity Framework Core 2 - 外键约束
Entity Framework Core - EF Core 2.2 - 'Point.Boundary' 属于接口类型('IGeometry')