一个与HasForeignKey为零或一

joo*_*zek 31 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我想使用流畅的映射来映射它们.Employee表的列'person_id'是不可为空的.我试过以下:

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));
Run Code Online (Sandbox Code Playgroud)

但它失败了:

System.Data.Entity.ModelConfiguration.ModelValidationException:在模型生成期间检测到一个或多个验证错误:

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

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

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

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

Ser*_*kiy 49

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

Property(e => e.PersonId).HasColumnName("person_id");
HasRequired(e => e.Person)
    .WithMany()
    .HasForeignKey(p => p.PersonId);
Run Code Online (Sandbox Code Playgroud)

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


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

public int PersonId { get { return Person.Id; } }
Run Code Online (Sandbox Code Playgroud)

并使用您的原始映射

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee)
    .Map(m => m.MapKey("person_id"));
Run Code Online (Sandbox Code Playgroud)

  • 这是一种愚蠢的方式,必须配置这种关系,因为失败了..HasRequired().WithOptional()`流畅的语法,EF应该只添加`.HasForeignKey()`到上面的流利链或不提供上述链一点都不 (32认同)

joe*_*dev 5

There's actually a better way to do this:

HasKey(e => e.PersonId);

HasRequired(e => e.Person)
    .WithOptional(p => p.Employee);
Run Code Online (Sandbox Code Playgroud)

Note that you no longer need the Employee.Id property with this approach, as it was superfluous in terms of a 1 to 0 or 1 relationship in the first place.