EF Code First 1:0..1关系错误:多重性在关系'EFEmployee_Identity'

时间:2015-06-24 20:55:06

标签: c# entity-framework foreign-keys data-annotations

完整错误:

  

在模型生成期间检测到一个或多个验证错误:

     

EFEmployee_Identity_Source ::多重性在关系'EFEmployee_Identity'中的角色'EFEmployee_Identity_Source'中无效。由于Dependent Role属性不是关键属性,因此Dependent Role的多重性的上限必须为'*'。

我正在处理三种类型的实体:EFEmployee,EFPerson和EFOffice。我收到此错误有点奇怪,因为我正在测试的代码只创建了一个EFOffice实体的实例。无论如何,这里是EFEmployee实体类:

[Table("employee_entity")]
public class EFEmployee : EFBusinessEntity
{
    [ForeignKey("Office")]
    public Guid OfficeID { get; set; }

    [ForeignKey("Identity")]
    public Guid PersonID { get; set; }

    [Column("hire_date")]
    public DateTime HireDate { get; set; }

    [Column("job_title")]
    public byte[] JobTitle { get; set; }

    [Column("salary")]
    public int Salary { get; set; }

    [Column("certifications")]
    public byte[] Certifications { get; set; }

    [Column("vacation_time")]
    public int VacationTime { get; set; }

    [Column("sick_time")]
    public int SickTime { get; set; }

    public virtual EFOffice Office { get; set; }

    public EFPerson Identity { get; set; }

    public virtual EFEmployee ReportingTo { get; set; }
}

这是我的EFPerson实体类:

[Table("person_entity")]
public class EFPerson : EFBusinessEntity
{
    [Column("first_name")]
    [StringLength(50)]
    public string FirstName { get; set; }

    [Column("last_name")]
    [StringLength(50)]
    public string LastName { get; set; }

    [Column("phone_num")]
    public uint? PhoneNum { get; set; }

    [Column("date_of_birth")]
    public DateTime DateOfBirth { get; set; }

    public EFEmployee Employee { get; set; }
}

您可以看到它们都继承自EFBusinessEntity,即:

[Table("business_entity")]
public abstract class EFBusinessEntity : IBusinessEntity
{
    [Column("tenant_id")]
    public Guid TenantId
    {
        get;
        set;
    }

    [Column("id")]
    [Key]
    public Guid Id
    {
        get;
        set;      
    }
}

正如您所看到的,EFEmployee和EFPerson之间存在一对一或零关系,EFEmployee是依赖关系,因为可能有一个人不是员工,但是不可能也不是一个人的员工。由于EFEmployee是依赖方,我在EFEmployee中添加了一个PersonID,上面的数据注释(属性?)表示它是Person的外键:

[ForeignKey("Identity")]
public Guid PersonID { get; set; }

我认为我已经明确表示Entity Framework这是一个1:0..1的关系。有没有人知道如何解决这个错误使用数据注释(或属性,无论属性上面的那些方括号)。我不能使用流畅的API,原因是我没有进入。

2 个答案:

答案 0 :(得分:1)

通常,在Entity Framework中使用1:0..1关系时,从属方需要使用其主键作为外键。幸运的是,对于你的情况,这似乎不是一个坏主意。你需要:

  1. 删除THREE.PointCloud属性
  2. EFEmployee.PersonID添加到[ForeignKey("Id")]
  3. 编辑:可能无法正常工作,因为键和导航属性位于不同的类中。请参阅this

    EFEmployee.Identity继承EFEmployee似乎也可能是一个可行的选择。继承默认使用TPH,但如果要使用TPT(每个类型的表),请将EFPerson属性添加到您的类型中。

答案 1 :(得分:0)

我做了一些更多的模型,发现了什么是错的。所以我把外键属性保存在EFPerson.Identity中,就像jjj建议的那样:

def create(value: String) = Map(value -> 1)

def mergeVals(x: Map[String, Int], value: String) = {
    val count = x.getOrElse(value, 0) + 1
    x ++ Map(value -> count)
}

def mergeCombs(x: Map[String, Int], y: Map[String, Int]) = {
    val keys = x.keys ++ y.keys
    keys.map((k: String) => (k -> (x.getOrElse(k, 0) + y.getOrElse(k, 0)))).toMap
}

val counts = persons.combineByKey(create, mergeVals, mergeCombs)

counts.flatMap { case (x: String, counts: Map[String, Int]) =>  {
    val sum = counts.values.sum.toDouble
    counts.map { case (k: String, v: Int) => (x, k, v, sum.toInt, v / sum) }
}}

然后,我必须做的另一个改变是在EFPerson课程中。在我的EFPerson课程中,我获得了EFEmployee的导航属性:

[ForeignKey("PersonID")]
public virtual EFPerson Identity { get; set; }

然而,由于这是与EFEmployee作为依赖方(即非必要方)的1:0..1关系,我删除了该导航属性,当我运行我的测试时它起作用。