已经读了一段时间关于这个的文章,但仍然有一些不合理的地方。生成包含这两个类的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设置中看到的,我让它根据需要将外键从ChecklistFilled类映射到ItemsFilled类,但是当我运行enable migrations命令时,会得到错误
ItemsFilled_Device_Target_ItemsFilled_Device_Source::关系约束中从属角色和主体角色中的属性数必须相同
从表面上看,它试图告诉我,我必须在每一个类中拥有相同数量的属性——这听起来很荒谬。所以我不确定我需要做什么来解决这个问题并将ChecklistID作为FK放入ItemsFilled表中

最佳答案

如果我理解正确,你想要的是一种关系,一个清单与一个清单相关,一个清单与一个清单相关。
若要实现此一对多关系,应重新定义实体中的属性,如下所示:

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实体中包含了一些注释或映射。

关于c# - 相关角色和主要角色中的代码优先外键错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40293375/

10-16 13:45