【问题标题】:How to delete Many - Many Relationship (Only Joining Table)如何删除多对多关系(仅连接表)
【发布时间】:2019-12-20 14:31:15
【问题描述】:

我在 ASP.NET Core 应用程序中使用 Entity Framework Core。我希望能够删除多对多关系表中的连接链接行(其中只有 table1Id 和 table2Id 列链接多对多关系),但我唯一的选择是

1) SetNull(我假设尝试将 TABLE2 上的 table2Id 列设置为 null,因为我无法执行更新数据库,它告诉我原因是因为它无法设置外键 id 列为空)

2) 限制(这是一个创可贴修复,因为它允许我推送,但现在我的用户在删除之前撤消所有关系之前无法删除)

3) 级联(这会尝试删除所有内容,绝对不是我想要的)

似乎不仅仅是“删除关系”选项

我尝试将链接类中的 id 属性设置为可为空(参见代码)

public class PregenProfessionArchetypeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<PregenProfessionArchetype_ParentSkill_LinkModel> TrainedParentSkills { get; set; } = new List<PregenProfessionArchetype_ParentSkill_LinkModel>();
    public ICollection<PregenProfessionArchetype_ChildSkill_LinkModel> ChildSkills { get; set; } = new List<PregenProfessionArchetype_ChildSkill_LinkModel>();
    public ICollection<PregenProfessionArchetype_Technique_LinkModel> Techniques { get; set; } = new List<PregenProfessionArchetype_Technique_LinkModel>();
    public ICollection<PregenProfessionArchetype_Talent_LinkModel> Talents { get; set; } = new List<PregenProfessionArchetype_Talent_LinkModel>();
}


public class PregenProfessionArchetype_ChildSkill_LinkModel
{
    public int PregenProfessionArchetypeId { get; set; }
    public PregenProfessionArchetypeModel PregenProfessionArchetype { get; set; }
    public int ChildSkillId { get; set; }
    public ChildSkillModel ChildSkill { get; set; }
}

public class PregenProfessionArchetype_ParentSkill_LinkModel
{
    public int? PregenProfessionArchetypeId { get; set; }
    public PregenProfessionArchetypeModel PregenProfessionArchetype { get; set; }
    public int? ParentSkillId { get; set; }
    public ParentSkillModel ParentSkill { get; set; }
}

public class ChildSkillModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public int ParentSkillId { get; set; }
    [Display(Name = "Parent Skill")]
    public ParentSkillModel ParentSkill { get; set; }
    public int Cost { get; set; } = 1;


    public ICollection<PregenProfessionArchetype_ChildSkill_LinkModel> PregenProfessionArchetypeLink { get; set; } = new List<PregenProfessionArchetype_ChildSkill_LinkModel>();
}


        // Application Context File Overwritting (Child is same and left out talent)
        builder.Entity<PregenProfessionArchetype_ParentSkill_LinkModel>()
            .HasKey(ttp => new { ttp.ParentSkillId, ttp.PregenProfessionArchetypeId });

        builder.Entity<PregenProfessionArchetype_ParentSkill_LinkModel>()
            .HasOne<PregenProfessionArchetypeModel>(tm => tm.PregenProfessionArchetype)
            .WithMany(tpp => tpp.TrainedParentSkills)
            .HasForeignKey(tm => tm.PregenProfessionArchetypeId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Entity<PregenProfessionArchetype_ParentSkill_LinkModel>()
            .HasOne<ParentSkillModel>(tm => tm.ParentSkill)
            .WithMany(tmm => tmm.PregenProfessionArchetypeLink)
            .HasForeignKey(tm => tm.PregenProfessionArchetypeId)
            .OnDelete(DeleteBehavior.Restrict);

我唯一可以推送的时间是设置为受限时。该代码显示了类及其关系的示例

错误信息:SetNull

Failed executing DbCommand (81ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER TABLE [PregenProfessionArchetype_ParentSkill_LinkModel] ADD CONSTRAINT [FK_PregenProfessionArchetype_ParentSkill_LinkModel_ParentSkillModel_PregenProfessionArchetypeId] FOREIGN KEY ([PregenProfessionArchetypeId]) REFERENCES [ParentSkillModel] ([Id]) ON DELETE SET NULL;

【问题讨论】:

  • 那么...你想如何删除它们?只是从父集合中删除它们?试过var toRemove = dbContext.Set&lt;PregenProfessionArchetype_ChildSkill_LinkModel&gt;().FirstOrDefault(x =&gt; ....); dbContext.Remove(toRemove); dbContext.SaveChanges();
  • 我只是想一起删除他们的链接。例如,如果我要删除一个父技能并且它有与之关联的 PregenProfessionalArchetypes,那么它只会删除它与 Pregens 而不是 Pregens 本身的链接

标签: asp.net-core-mvc entity-framework-core


【解决方案1】:

如果你想在删除父技能时只删除连接表的链接和父表的行,你可以使用Cascadedelete,这是required relationships的默认行为

Delete behaviors 在 DeleteBehavior 枚举器类型中定义,可以传递给 OnDelete fluent API 以控制删除主体/父实体或切断与依赖/子实体的关系是否应该对依赖/子实体。

在您的场景中,PregenProfessionArchetype_ParentSkill_LinkModelPregenProfessionArchetypeModelParentSkillModel 的依赖/子实体。所以当删除 Parent 时,它从 PregenProfessionArchetype_ParentSkill_LinkModel Table 的链接会因为 Cascade 而被自动删除,但 Pregens 不会被删除。如果您还想删除仅连接到该父级的 Pregen,则必须手动执行。

参考:Entity Framework Core Code-First: Cascade delete on a many-to-many relationship

【讨论】:

  • 在表“TechniquePrerequisitesLink”上引入 FOREIGN KEY 约束“FK_TechniquePrerequisitesLink_TechniqueModel_TechniqueModelId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。查看以前的错误。
  • 这是我使用其中一个模型时遇到的错误
  • 另外,当我设置为级联时,它会删除包括链接模型在内的所有内容
  • 所以我说的一切都从头开始......我不聪明......级联按预期运行
猜你喜欢
  • 2021-07-12
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多