指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.- 如何? [英] Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. - How?

查看:269
本文介绍了指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.- 如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以很容易地复制此问题,但是我不知道解决该问题的正确方法.

This issue can be replicated easily, but I do not know the correct way to resolve it.

例如,您有一个团队类和一个游戏类.每场比赛有两个团队.使用标准OOTB EF命名约定时,运行 dotnet ef数据库更新时会遇到以下错误( dotnet ef迁移添加将无错误运行).

For example, you have a Team class and a Game class. Each Game has two Teams. When using standard OOTB EF naming conventions, you will run into the following error when running dotnet ef database update (dotnet ef migrations add will run without error).

课程:

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

确保将这两个类添加到您的DbContext中:

Make sure to add the two classes into your DbContext:

public virtual DbSet<Team> Teams { get; set; }
public virtual DbSet<Game> Games { get; set; }

我收到的错误是:

在表游戏"上引入外键约束"FK_Games_Teams_Team2ID"可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.

我以前通过将 Team1ID Team2ID 都设置为空来解决此问题.但这显然不是适当的解决方案.没有恰好有两个团队的游戏就不可能存在(在这种情况下,假设这是一场足球比赛).另外,如果一个团队参加(或参加)至少一场比赛,则不应删除该团队.

I have previously worked around this issue by making both Team1ID and Team2ID nullable. But, that is obviously not the appropriate solution. A Game cannot exist without having exactly two Teams (in this scenario... let's say it's a game of soccer). Also, a Team should not be able to be deleted if it's participating (or participated) in at least one Game.

解决此问题的适当方法是什么?并且,如果指定ON DELETE NOT ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束,您该怎么做?

What is the appropriate way to resolve this issue? And if it is specifying ON DELETE NOT ACTION or ON UPDATE NO ACTION, or modifying other FOREIGN KEY constraints, how do you do so?

推荐答案

在EF Core中,关系的级联行为通过要求的关系(与您一样).

In EF Core, the cascading behavior of a relationship is configured through OnDelete relationship Fluent API (by default it is Cascade for required relationships like yours).

棘手的部分是如何访问该API,因为没有直接方法(例如,类似 modelBuilder.Relation< TPrincipal,TDependent>(...)有,但这种API不存在),因此至少需要从实体类型构建器开始,然后再加上适当的 Has {One | Many} / With {One | Many} 对.正确地说,我的意思是在存在时传递相应的导航属性.否则,会导致意外的其他关系/FK,因为EF Core会将未映射的导航属性映射到默认的常规关系/FK.

The tricky part is how to get access to that API, since there is no direct way (e.g. something like modelBuilder.Relation<TPrincipal, TDependent>()... would have been nice to have, but such API does not exist), so at minimum you need to start with entity type builder, followed by proper Has{One|Many} / With{One|Many} pair. By proper I mean passing the corresponding navigation property when exists. Failing to do so would lead to unexpected additional relationships / FKs since EF Core will map the unmapped navigation properties to default conventional relationships / FKs.

您的情况是这样的:

modelBuilder.Entity<Game>()
    .HasOne(e => e.Team1)
    .WithMany();

modelBuilder.Entity<Game>()
    .HasOne(e => e.Team2)
    .WithMany();

现在您可以配置级联行为,FK属性/约束名称等.

Now you can configure the cascade behavior, FK property / constraint names etc.

在这种情况下,只需为两个关系插入 .OnDelete(DeleteBehavior.Restrict),就可以完成:

In this particular case, just insert .OnDelete(DeleteBehavior.Restrict) for both relationships and you are done:

modelBuilder.Entity<Game>()
    .HasOne(e => e.Team1)
    .WithMany()
    .OnDelete(DeleteBehavior.Restrict); // <--

modelBuilder.Entity<Game>()
    .HasOne(e => e.Team2)
    .WithMany()
    .OnDelete(DeleteBehavior.Restrict); // <--

有关更多信息,请参见文档的"EF核心API参考" 部分.

For more info, see Relationships and EF Core API Reference sections of the documentation.

这篇关于指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.- 如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆