简体   繁体   English

在表中引入 FOREIGN KEY 约束时如何避免循环?

[英]How to avoid cycles when introducing FOREIGN KEY constraint in a table?

I'm using code-first approach with EF Core 6 to construct the database and its tables.我在EF Core 6中使用代码优先方法来构建数据库及其表。 The problem is that when I update the database, I get an error regarding cycles or multiple cascade paths.问题是当我更新数据库时,我收到关于循环或多个级联路径的错误。 I searched the same questions but none of them could solve my problem.我搜索了相同的问题,但没有一个可以解决我的问题。 My entity classes are:我的实体类是:

public class User
{
    [Key]
    public int UserId { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Username { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Password { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string UserRole { get; set; }
    [Required]
    public bool IsActive { get; set; }
    [Required]
    public bool CanAccessNotifications { get; set; }
    [Required]
    public bool CanAccessMessages { get; set; }
    [Required]
    public bool CanAccessFiles { get; set; }
    [Required]
    public bool CanAccessPmDatabase { get; set; }
    [Required]
    public bool CanMakeChangesToPmDatabase { get; set; }
    [Required]
    public bool IsLocked { get; set; }
    [Required]
    public bool CanLocked { get; set; }

    //Navigation properties
    public virtual CostCenter CostCenter { get; set; }
    public virtual List<PmSchedule> PmSchedules { get; set; }
}

public class ServiceType
{
    [Key]
    public int ServiceTypeId { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Title { get; set; }
    [Required]
    public bool IsActive { get; set; } = true;

    //Navigation properties
    public virtual List<PmDataSet> PmDataSets { get; set; }
    public virtual List<PmSchedule> PmSchedules { get; set; }
}

public class PmSchedule
{
    [Key]
    public long PmScheduleId { get; set; }
    [Required]
    public long PmNumber { get; set; }
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ScheduledStartDate { get; set; }
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ScheduledEndDate { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string MainFileName { get; set; }
    [DataType(DataType.Text)]
    public string? UploadedFileName { get; set; }
    [Required]
    public int MainUploader { get; set; }
    public int? Uploader { get; set; }
    [DataType(DataType.DateTime)]
    public DateTime? CompletionDate { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string? Status { get; set; }

    //Navigation properties
    public virtual CostCenter CostCenter { get; set; }
    public virtual ServiceType ServiceType { get; set; }
}

public class PmDataSet
{
    [Key]
    public long PmDataSetId { get; set; }
    [Required]
    public long PmNumber { get; set; }
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ScheduledStartDate { get; set; }
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime ScheduledEndDate { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string WorkOrderNumber { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Priority { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Activity { get; set; }
    [DataType(DataType.DateTime)]
    public DateTime? StartTime { get; set; }
    [DataType(DataType.DateTime)]
    public DateTime? EndTime { get; set; }
    [Required]
    public int ActualDuration { get; set; }
    [Required]
    public int StandardDuration { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Executor { get; set; }
    [DataType(DataType.Text)]
    public string? Expaination { get; set; }


    //Navigation properties
    public virtual ServiceType ServiceType { get; set; }
    public virtual CostCenter CostCenter { get; set; }
    public virtual Equipment Equipment { get; set; }
}

public class Equipment
{
    [Key]
    public long EquipmentId { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string EquipmentCode { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string EquipmentTitle { get; set; }

    //Navigation properties
    public virtual CostCenter CostCenter { get; set; }
    public virtual List<PmDataSet> PmDataSets { get; set; }
}

public class CostCenter
{
    [Key]
    public int CostCenterId { get; set; }
    [Required]
    [DataType(DataType.Text)]
    public string Title { get; set; }
    [Required]
    public bool IsActive { get; set; } = true;


    //Navigation properties
    public virtual List<PmDataSet>? PmDataSets { get; set; }
    public virtual List<PmSchedule>? PmSchedules { get; set; }
    public virtual List<Equipment>? Equipments { get; set; }
    public virtual List<User>? Users { get; set; }
}

My context class:我的上下文 class:

protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

    }

I get the following error when update the database:更新数据库时出现以下错误:

Introducing FOREIGN KEY constraint 'FK_PmDataSets_Equipments_EquipmentId' on table 'PmDataSets' may cause cycles or multiple cascade paths.在表“PmDataSets”上引入 FOREIGN KEY 约束“FK_PmDataSets_Equipments_EquipmentId”可能会导致循环或多个级联路径。 Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 Could not create constraint or index.无法创建约束或索引。 See previous errors.请参阅以前的错误。

you need to add some extra config like this:您需要添加一些额外的配置,如下所示:

    protected override void OnModelCreating(ModelBuilder mb)
{   
    var pmConfig = mb.Entity<PmDataSet>();
    pmConfig.HasOne(n => n.Equipment).WithMany(n => n.PmDataSets).OnDelete(DeleteBehavior.NoAction);
}

the problem is your Equipment model or/and some others already has at least one cascade delete relation, so if you add another cascade delete relation there will be a chain deletion if one of these entities got deleted.问题是您的设备 model 或/和其他一些已经具有至少一个级联删除关系,因此如果您添加另一个级联删除关系,如果其中一个实体被删除,则会出现链式删除。 so you need to tell ef that some/none of these relations are not cascading while deleting.所以你需要告诉 ef 这些关系中的一些/没有一个在删除时没有级联。

(A) <-- cascade --> (B) (A) <-- 级联 --> (B)

(B) <-- cascade --> (C) so there will be a logical cascade between A and C, that is not arbitrary. (B) <-- 级联 --> (C) 所以在 A 和 C 之间会有一个逻辑级联,这不是任意的。

with a little playing with that config you will solve your problem;)稍微玩一下该配置,您将解决您的问题;)

-------- update to answer the commented question u can go by ef convictions: -------- 更新以回答评论的问题,您可以通过 ef 信念 go:

public User MainUploader { get; set; }
[Required]
public int MainUploaderId { get; set; }
public User Uploader { get; set; }
public int? UploaderId { get; set; }

you also can use [ForeignKey("fkName")] annotation if you want to use another way of naming your properties, or use fluent API ForeignKey(a=> a.something) method or its overlods.如果您想使用另一种命名属性的方式,也可以使用 [ForeignKey("fkName")] 注释,或者使用流畅的 API ForeignKey(a=> a.something) 方法或其重载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 表&#39;UsageSummaries&#39;上的多态与引入FOREIGN KEY约束可能会导致循环或多个级联路径 - Polymorphism vs Introducing FOREIGN KEY constraint '' on table 'UsageSummaries' may cause cycles or multiple cascade paths ef核心2-在表&#39;Y&#39;上引入FOREIGN KEY约束&#39;X&#39;可能会导致循环或多个级联路径 - ef core 2 - Introducing FOREIGN KEY constraint 'X' on table 'Y' may cause cycles or multiple cascade paths 在表上引入外键约束可能会导致循环或多个级联路径 - Introducing Foreign key Constraint on table may cause cycles or multiple cascade paths 在表“模型”上引入FOREIGN KEY约束“列”可能会导致循环或多个级联路径 - Introducing FOREIGN KEY constraint 'Column' on table 'Model' may cause cycles or multiple cascade paths 实体框架:在表 '' 上引入 FOREIGN KEY 约束 '' 可能会导致循环或多个级联路径 - Entity Framework: Introducing FOREIGN KEY constraint '' on table '' may cause cycles or multiple cascade paths 当不需要属性时,引入外键约束可能会导致循环或多个级联路径 - Introducing Foreign Key Constraint may cause cycles or multiple cascade paths when property is not required 实体框架 - 引入外键约束可能会导致周期 - Entity Framework - Introducing foreign key constraint may cause cycles 在表table上引入FOREIGN KEY约束键可能会导致循环或多个级联路径。 指定ON DELETE…错误 - Introducing FOREIGN KEY constraint key on table table may cause cycles or multiple cascade paths. Specify ON DELETE … Error 在表“模型”上引入FOREIGN KEY约束“ FK_dbo.Models_dbo.Makes_MakeId”可能会导致循环或多个级联路径 - Introducing FOREIGN KEY constraint 'FK_dbo.Models_dbo.Makes_MakeId' on table 'Models' may cause cycles or multiple cascade paths 在表 'XY' 上引入 FOREIGN KEY 约束 'FK_XY' 可能会导致循环或多个级联路径。 指定 ON DELETE NO ACTION - Introducing FOREIGN KEY constraint 'FK_XY' on table 'XY' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM