实体框架——使用相同Key的多个1到0.1关系

本文关键字:关系 Key 框架 实体 | 更新日期: 2023-09-27 18:07:24

我已经阅读了尽可能多的关于这个主题的帖子,但我所尝试的解决方案似乎都不起作用。我有一个现有的数据库,并创建了一个新的代码首先从现有的数据库项目。

我有一个名为Thing的基本表。每个对象在该表中都有一条记录,使用Id作为唯一主键。每个其他对象都继承于此,但它们在子表中使用相同的Id,而不在子表中使用新的Identity列。有效地给每个"东西"一个唯一的Id:

public class Thing
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class Car
{
    public int Id { get; set; }
    //other properties
}
public class Person
{
    public int Id { get; set; }
    //other properties
}
public class Color
{
    public int Id { get; set; }
    //other properties
}

每条新记录首先在'Thing'中创建一个项目,然后使用该Id值在其各自的表中创建一个新记录,创建多个1到0。1关系,其中派生表上的Id字段也是到Thing的FK。

事物1到0汽车

事物1到0人

事物1到0颜色

等等

我尝试了许多不同的数据注释和流畅的API组合,但它总是回到相同的错误:

'无法检索Model.Car的元数据'。无法确定类型"模型"之间关联的主要结束。Thing'和'Model.Car'。此关联的主体端必须使用关系流畅API或数据注释显式配置。

我确实设法通过使用virtual和反向注释并将Id字段设置为Key和ForeignKey来解决此错误,但随后消息跳转到Person。如果将其设置为与Car相同,则消息将返回到Car。

似乎我可以回去为每个子表创建一个正常的外键,但这是很多工作,我相信有可能以某种方式得到这个工作。最好使用流畅的API

实体框架——使用相同Key的多个1到0.1关系

如果要使用数据注释,则需要将依赖实体的PK也声明为FK:

public class Thing
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Car Car{get;set;}
}
public class Car
{
    [Key,ForeignKey("Thing")]
    public int ThingId { get; set; }
    //other properties
    public virtual Thing Thing{get;set;}
}

如果你打算使用Fluent Api(从模型中删除属性),配置将是这样的:

modelBuilder.Entity<Car>().HasRequired(c=>c.Thing).WithOptional(t=>t.Thing);

根据所指定的多重性,只有Thing是主体,Car是从属才有意义,因为Thing可以不存在Car,但Car必须有Thing

正如你所看到的,你不需要指定ThingId是这个关系的FK。这是因为实体框架要求将依赖项的主键用作外键。因为没有选择,Code First会为你推断。

更新

再次阅读你的问题,我认为你正在尝试创建一个层次结构。在这种情况下,您可以使用每类型表(TPT)方法。