如何在TPH TPT对象之间映射外键 - 实体框架代码首先 [英] How to map foreign keys between TPH TPT objects - Entity Framework Code First

查看:124
本文介绍了如何在TPH TPT对象之间映射外键 - 实体框架代码首先的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有以下对象集。

  public class Form 
{
public int FormId {get;组; }
public DateTime DateCreatedOn {get;组; }
public string Status {get;组; }
}

//这是使用Form
中的TPT继承[Table(FormA)]
public class FormA:Form
{
public string ExtraInfoA {get;组; }
public virtual ICollection< Child>孩子
}

//这是使用Form
中的TPT继承[Table(FormB)]
public class FormB:Form
{
public string ExtraInfoB {get;组; }
public virtual ICollection< Adult>成人
}

public class Person
{
public int PersonId {get;组; }
public int FormId
public DateTime DateOfBirth {get;组; }
public string FirstName {get;组; }
public string LastName {get;组;
}

//这是从Person
中使用TPH继承public class Adult:Person
{
public int HowManyCars {get;组; }
public string NationalInsuranceNo {get;组; }
[ForeignKey(FormId)]
public virtual FormB FormB {get;组;
}

//这是使用Person
中的TPH继承public class Child:Person
{
public int HowManyToys {get;组; }
public string SchoolName {get;组; }
[ForeignKey(FormId)]
public virtual FormA FormA {get;组;
}

这将为表单创建3个表格 Form FormA FormB ,其中包含相应的字段。它还为 Person 创建1个表。



问题是当我们依赖该约定而不指定 ForeignKey 属性 Person 表包含2个附加的外键列。



但是,当我们指定 ForeignKey 属性(如上面的代码)时,我们收到以下错误消息。

 `外键组件FormId不是Child类型的声明属性。验证它没有被明确排除在模型中,并且它是一个有效的原始属性。

FormId 绝对是 Child 的属性,所以我不知道发生了什么问题。



我们的现实世界情况比上述情况复杂得多,所以我想现在得到它,而不是有多个外键。



非常感谢任何帮助。

解决方案

父实体中的外键和子实体中的导航属性。它们必须在同一实体中定义。您尝试做的甚至在数据库中无效,因为您无法对列执行条件外键约束 - 对 FormA FormB的约束将被应用于每个记录,您将永远无法插入任何记录(因为它总是违反约束到 FormA 或<$ c $简单来说:您需要父母中的单一导航属性或每个孩子单独的外键。




We have the following set of objects.

public class Form
{
    public int FormId { get; set; }
    public DateTime DateCreatedOn { get; set; }
    public string Status { get; set; }
}

// This is using TPT inheritance from Form
[Table("FormA")]
public class FormA : Form
{
    public string ExtraInfoA { get; set; }
    public virtual ICollection<Child> Children
}

// This is using TPT inheritance from Form
[Table("FormB")]
public class FormB : Form
{
    public string ExtraInfoB { get; set; }
    public virtual ICollection<Adult> Adults
}

public class Person
{
    public int PersonId { get; set; }
    public int FormId
    public DateTime DateOfBirth { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

// This is using TPH inheritance from Person
public class Adult : Person
{
    public int HowManyCars { get; set; }
    public string NationalInsuranceNo { get; set; }
    [ForeignKey("FormId")]
    public virtual FormB FormB { get; set; }
}

// This is using TPH inheritance from Person
public class Child : Person
{
    public int HowManyToys { get; set; }
    public string SchoolName { get; set; }
    [ForeignKey("FormId")]
    public virtual FormA FormA { get; set; }
}

This creates 3 tables for the forms Form, FormA, and FormB, all with the appropriate fields in them. It also creates 1 table for Person.

The problem is When we rely on the convention and don't specify the ForeignKey attribute the Person table contains 2 additional foreign key columns.

However when we do specify the ForeignKey attribute (as in the code above) we get the following error message.

`The foreign key component 'FormId' is not a declared property on type 'Child'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.`

FormId is definitely a property of Child so I'm not sure what is going wrong.

Our real world situation is a lot more complicated that the situation above so I'd like to get it right now rather tham have multiple foreign keys.

Any help is very much appreciated.

解决方案

You cannot define foreign key in the parent entity and navigation property in the child entity. They must both be defined in the same entity. What you are trying to do is even not valid in the database because you cannot have conditional foreign key constraint on the column - constraints to both FormA and FormB will be applied for every record and you will never be able to insert any record (because it would always violate constraint to FormA or FormB).

In short: You need either single navigation property in parent or separate foreign key for every child.

这篇关于如何在TPH TPT对象之间映射外键 - 实体框架代码首先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆