【问题标题】:Unable to determine the principal end of an association between the types Error无法确定类型之间关联的主体端错误
【发布时间】:2014-02-18 09:36:52
【问题描述】:

这是我的两个模型,我在更新数据库时在 asp.net mvc5 codefirst 上收到此错误

错误:无法确定类型“ModulericaV1.Areas.Hr.Models.HrDepartment”和“ModulericaV1.Areas.Hr.Models.HrPerson”之间关联的主体端。此关联的主体端必须使用关系流式 API 或数据注释显式配置。

部门

 public class HrDepartment
    {
        [Key]
        public int Id { get; set; }

        [Display(Name = "Departman Adı")]
        public string Name { get; set; }

        public int? HrDepartmentId { get; set; }

        [ForeignKey("HrDepartmentId")]
        public virtual HrDepartment RelatedDepartment { get; set; }

        public int HrPersonId { get; set; }
        public virtual HrPerson HrPerson { get; set; }

    }

public class HrPerson
    {
        public int Id { get; set; }
        [Display(Name = "Ad")]
        public string Name { get; set; }

        [Display(Name = "Departman")]
        public int HrDepartmentId { get; set; }
        public virtual HrDepartment HrDepartment { get; set; }

    }

【问题讨论】:

    标签: asp.net-mvc data-annotations code-first


    【解决方案1】:

    您必须覆盖 DbContext 的 OnModelCreating 方法。 试试这样的:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<HrDepartment>().HasRequired(a=>a.HrPerson ).WithRequiredDependent(b=>b.HrDepartment);
    }
    

    或者这个:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<HrDepartment>().HasRequired(a=>a.HrPerson ).WithRequiredPrincipal(b=>b.HrDepartment);
    }
    

    这些之间的区别在于主体端。 我不得不说我没有尝试,只是写我记得的东西,所以可能会有一些错误,但是这样做你将能够修复那个错误。

    此外,您还可以设置级联删除设置.WillCascadeOnDelete(false)(默认值为true)。

    回答评论问题: 我认为 EF 不会创建数据库约束,因为如果两者都需要,那么您不能插入 A,因为您需要已经创建 B(否则检查失败)并且 B 还不能创建,因为它需要 A(对于同样的原因)。因此,您可以不受限制地工作,但您必须在每次 SaveChanges() 或重新设计模型之前以编程方式进行检查。事实上,我认为你没有要求-要求的关系,而是1:N,因为一个部门必须有一个负责,但一个人可以负责零到N个部门。

    因此我要做的是:

    1) 保持 HrDep 不变

    2) 删除

    [Display(Name = "Departman")]
            public int HrDepartmentId { get; set; }
            public virtual HrDepartment HrDepartment { get; set; }
    

    3) 替换

    modelBuilder.Entity<HrDepartment>().HasRequired(a=>a.HrPerson ).WithRequiredPrincipal(b=>b.HrDepartment);
    

    modelBuilder.Entity<HrDepartment>().HasRequired(a => a.HrPerson ).WithMany().WillCascadeOnDelete(false);
    

    注意,在更新db时,由于现有的数据库结构,会出现错误,所以最快的方法是删除数据库,让EF重新创建它。

    希望对您有所帮助,祝您有美好的一天,

    阿尔伯托

    【讨论】:

    • 第二个是解决方案,谢谢 :) 但是您能否解释更多或如何从链接或教程中学习?
    • 还有一件事,使用此选项,脚手架不会为部门人员和部门人员创建下拉列表...只是创建 HrPersonId 和 HrDepartmentId
    • 快速资源:msdn.microsoft.com/en-us/data/jj591620.aspx 完整资源:amazon.com/Programming-Entity-Framework-Julia-Lerman/dp/… 以及 Julia Lerman 的其他书籍
    • 感谢 Alberto,但它似乎不起作用。现在表之间没有关系。我可以放 personid=44 但没有人有这个 id
    • Alberto,我在这个问题上工作了 3 天,但没有解决,你能帮我解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 2014-08-14
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多