Car*_* Jr 5 c# entity-framework entity-framework-core
这个问题很容易复制,但我不知道解决它的正确方法。
例如,您有一个Team类和一个Game类。每场比赛有两支球队。使用标准 OOTB EF 命名约定时,在运行dotnet ef database update时会遇到以下错误(dotnet ef migrations add将正常运行)。
课程:
public class Team
{
[Required]
public int TeamID { get; set; }
public string TeamName { get; set; }
}
public class Game
{
[Required]
public int GameID { get; set; }
public int Team1ID { get; set; }
public Team Team1 { get; set; }
public int Team2ID { get; set; }
public Team Team2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
确保将这两个类添加到您的 DbContext 中:
public virtual DbSet<Team> Teams { get; set; }
public virtual DbSet<Game> Games { get; set; }
Run Code Online (Sandbox Code Playgroud)
我收到的错误是:
在表“Games”上引入 FOREIGN KEY 约束“FK_Games_Teams_Team2ID”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
我以前通过使Team1ID和Team2ID 都可以为空来解决这个问题。但是,这显然不是合适的解决方案。如果没有恰好两个团队,游戏就无法存在(在这种情况下......假设它是一场足球比赛)。此外,如果一个团队正在参加(或参加)至少一场比赛,则不应被删除。
解决此问题的适当方法是什么?如果它指定 ON DELETE NOT ACTION 或 ON UPDATE NO ACTION,或者修改其他 FOREIGN KEY 约束,你怎么做?
在 EF Core 中,关系的级联行为是通过OnDelete关系 Fluent API配置的(默认情况下,它Cascade用于像您这样的必需关系)。
棘手的部分是如何访问该 API,因为没有直接的方法(例如,像modelBuilder.Relation<TPrincipal, TDependent>()...这样的东西本来很好,但这样的 API 不存在),所以至少你需要从实体类型构建器开始,然后通过适当的Has{One|Many}/With{One|Many}对。正确的意思是在存在时传递相应的导航属性。不这样做会导致意外的额外关系/FK,因为 EF Core 会将未映射的导航属性映射到默认的常规关系/FK。
在你的情况下,它会是这样的:
modelBuilder.Entity<Game>()
.HasOne(e => e.Team1)
.WithMany();
modelBuilder.Entity<Game>()
.HasOne(e => e.Team2)
.WithMany();
Run Code Online (Sandbox Code Playgroud)
现在您可以配置级联行为、FK 属性/约束名称等。
在这种特殊情况下,只需插入.OnDelete(DeleteBehavior.Restrict)两个关系即可完成:
modelBuilder.Entity<Game>()
.HasOne(e => e.Team1)
.WithMany()
.OnDelete(DeleteBehavior.Restrict); // <--
modelBuilder.Entity<Game>()
.HasOne(e => e.Team2)
.WithMany()
.OnDelete(DeleteBehavior.Restrict); // <--
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅文档的关系和EF Core API 参考部分。
| 归档时间: |
|
| 查看次数: |
8919 次 |
| 最近记录: |