一个与HasForeignKey为零或一

时间:2013-09-10 13:11:08

标签: c# entity-framework fluent-entity-framework

我有两种模式:

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");
    }
}

我想使用流畅的映射来映射它们。 Employee表的列'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那样的方法

2 个答案:

答案 0 :(得分:46)

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

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

有关详细信息,请参阅One-to-One Foreign Key Associations文章。 BTW这将为人员表创建员工外键列,但没有其他方法可以单独使用导航属性和外键。


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

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

并使用原始地图

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

答案 1 :(得分:5)

实际上有更好的方法:

HasKey(e => e.PersonId);

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

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