从属角色和主体角色中的代码优先外键错误

本文关键字:角色 错误 代码 主体 | 更新日期: 2023-09-27 18:15:14

已经看了一段时间了,仍然有一些东西没有意义。创建包含以下两个类的MVC应用程序

public class ChecklistFilled
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int InternalChecklistFilledID { get; set; }
    public DateTime ChecklistFilledDate { get; set; }
    public int PersonnelID { get; set; }
    [ForeignKey("PersonnelID")]
    public virtual Personnel Personnel { get; set; }
    public int EquipmentID { get; set; }
    [ForeignKey("EquipmentID")]
    public virtual ICollection<Equipment> Equipment { get; set; }
    public virtual ItemsFilled ItemsFilled { get; set; }
}
public class ItemsFilled
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int InternalItemsFilledID { get; set; }
    public bool? DeviceCondition { get; set; }
    public int DeviceID { get; set; }
    [ForeignKey("DeviceID")]
    public virtual Device Device { get; set; }
    public int ChecklistFilledID { get; set; }
    [ForeignKey("ChecklistFilledID")]
    public virtual ICollection<ChecklistFilled> ChecklistFilled { get; set; }
}

和来自DBContext类的语句

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ItemsFilled>()
            .HasRequired(x => x.ChecklistFilled)
            .WithMany()
            .Map(x => x.MapKey("ChecklistFilledID"));
        base.OnModelCreating(modelBuilder);
    }

到目前为止,我发现很多帖子都有相当具体的程序员问题的解决方案,没有什么是直接的,足以让我作为一个新的开发人员在这里应用。从我所看到的DBContext设置来看,我让它根据需要将外键从checklistfill类映射到itemsfill类,但是当我运行enable-migrations命令时,我得到了错误

ItemsFilled_Device_Target_ItemsFilled_Device_Source::关系约束中从属角色和主体角色的属性数量必须相同

从表面上看,它试图告诉我在每个类中必须有相同数量的属性——这对我来说听起来很荒谬。所以我不确定我需要做些什么来解决这个问题,并将ChecklistID作为FK放入itemsfilling表

从属角色和主体角色中的代码优先外键错误

如果我理解正确的话,您想要的是一种关系,其中一个检查表与一个项目列表相关,而一个项目与一个检查表相关。

要实现这种一对多的关系,你应该在你的实体中重新定义属性,像这样:

public class ChecklistFilled
{
    ...
    public virtual ICollection<ItemsFilled> ItemsFilled { get; set; }
}
public class ItemsFilled
{
    ...
    public int CheckListFilledId { get; set; }
    [ForeignKey("CheckListFilledId")]
    public virtual ChecklistFilled ChecklistFilled { get; set; }
}

有了这个更改,您甚至不需要在OnModelInitialize中显式映射。实际上,您应该删除映射。

作为旁注,一般情况下,如果base.OnModelCreating(modelBuilder);是方法中的第一行。

迁移生成的表看起来像这样(为了清晰起见,我删除了一些不相关的属性):

        CreateTable(
            "dbo.ChecklistFilleds",
            c => new
                {
                    InternalChecklistFilledID = c.Int(nullable: false, identity: true),
                    ChecklistFilledDate = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.InternalChecklistFilledID);
        CreateTable(
            "dbo.ItemsFilleds",
            c => new
                {
                    InternalItemsFilledID = c.Int(nullable: false, identity: true),
                    DeviceCondition = c.Boolean(),
                    CheckListFilledId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.InternalItemsFilledID)
            .ForeignKey("dbo.ChecklistFilleds", t => t.CheckListFilledId, cascadeDelete: true)
            .Index(t => t.CheckListFilledId);

也许您应该考虑重命名您的实体,这些名称有点令人困惑,特别是当以复数形式组成表名时。我建议FilledCheckListFilledItem

同样,您得到的错误表明有问题的关系是ItemsFilled_Device_Target_ItemsFilled_Device_Source。它是关于DevicesItemsFilled。似乎你的代码包括一些注释或映射在Device实体,导致一个问题。