一比零或一与 HasForeignKey

本文关键字:HasForeignKey | 更新日期: 2023-09-27 18:30:45

我有两个模型:

public class Person
{
    public virtual int Id { get; set; }
    public virtual Employee Employee { get; set; } // optional
}
public class Employee
{
    public virtual int Id { get; set; }
    public virtual int PersonId { get; set; }
    public virtual Person Person {get; set; } // required
}
public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
    public EmployeeConfiguration()
    {
        Property(e=>e.PersonId) // I need this property mapped
            .HasColumnName("person_id")
            .HasColumnType("int");
    }
}

我想使用流畅的映射来映射它们。员工表具有不可为空的列"person_id"。我尝试了以下操作:

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));

但它失败了:

System.Data.Entity.ModelConfiguration.ModelValidationException : one 或在模型生成过程中检测到更多验证错误:

person_id:名称:类型中的每个属性名称必须是唯一的。财产 名称"person_id"已定义。

我需要 PersonId 属性本身,所以我基本上想要的是:

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .HasForeignKey(e => e.PersonId); // there is no such method

但是这里没有像HasForeignKey这样的方法

一比零或一与 HasForeignKey

好的,我想通了 - 你应该使用 WithMany(是的,不明显)以便在某些属性中存储外键:

Property(e => e.PersonId).HasColumnName("person_id");
HasRequired(e => e.Person)
    .WithMany()
    .HasForeignKey(p => p.PersonId);

有关详细信息,请参阅一对一外键关联一文。顺便说一句,这将为人员表创建员工外键列,但没有其他方法可以分别拥有导航属性和外键。


如果需要只读外键,可以将 PersonId 属性更改为:

public int PersonId { get { return Person.Id; } }

并使用您的原始映射

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));

实际上有一个更好的方法可以做到这一点:

HasKey(e => e.PersonId);
HasRequired(e => e.Person)
    .WithOptional(p => p.Employee);

请注意,使用此方法不再需要 Employee.Id 属性,因为它首先在 1 到 0 或 1 关系方面是多余的。