Entity framework 具有一对一关系和双向属性导航的EF6外键

Entity framework 具有一对一关系和双向属性导航的EF6外键,entity-framework,entity-framework-6,foreign-key-relationship,one-to-one,Entity Framework,Entity Framework 6,Foreign Key Relationship,One To One,当我使用双向导航时,我似乎无法让EF6生成FK 以下是我的类(为了简洁起见删除了一些属性): 我希望SystemConfiguration表有一个回到BaseSystem.Id的FK引用 以下是我的fluent API代码: modelBuilder.Entity<SystemConfiguration>() .HasRequired(x => x.System) .WithOptional(x => x.Configuration); 注意到它生成的S

当我使用双向导航时,我似乎无法让EF6生成FK

以下是我的类(为了简洁起见删除了一些属性):

我希望
SystemConfiguration
表有一个回到
BaseSystem.Id
的FK引用

以下是我的fluent API代码:

modelBuilder.Entity<SystemConfiguration>()
    .HasRequired(x => x.System)
    .WithOptional(x => x.Configuration);
注意到它生成的SQL不包括FK后,我删除了
BaseSystem.Configuration
属性,迁移会生成以下内容:

CreateTable(
    "MYDB.SYSTEMCONFIGURATION",
    c => new
        {
            ID = c.Decimal(nullable: false, precision: 10, scale: 0, identity: true),
            SYSTEM_ID = c.Decimal(nullable: false, precision: 10, scale: 0),
        })
    .PrimaryKey(t => t.ID)
    .ForeignKey("CISRF.BASESYSTEM", t => t.SYSTEM_ID, cascadeDelete: true);
我的SQL还按预期生成了“系统ID”编号(10,0)不为空的
,当我有双向导航时,它不会这样做


在仍然具有双向导航的情况下,我需要如何在
系统配置
表上生成FK?

使用一对一关系时,EF6使用子级中的
Id
列作为父级的FK,它不会为FK创建第二列,因为这将被视为一对多关系,因为第二列将允许父
Id
存在于许多子条目中,而作为FK的PK则不会

当您从父类中删除
配置
属性时,EF6知道您的子类有一个必需的
系统作为父类,但没有任何规定它应该是一对一的,因此EF6默认情况下将视为一对多关系,因为它创建了第二列,这将允许在多个子条目中使用相同的父条目

有些人可能会说,你可以为那一秒创建一个唯一索引 列作为FK,以避免具有相同的父id,但EF6不起作用 这样(也许他们认为这样做没有意义)


您尝试的第一个选项是配置一对一关系的正确方法,
SystemConfiguration
中的
Id
同时是一个PK和一个FK to
BaseSystem

您不能(EF限制)-请看。您的第一句话总结了这一切(关于一对多的说法也是正确的)。一开始很难注意到,因为按照惯例,我习惯于看到一个名为Parent_Id的FK。我从未想过在一对一的关系中使用该Id作为FK。所以我重新编辑了所有内容,现在它的配置与您所说的一样。@oscilatingcretin我在一家公司工作,他们也使用了
Parent\u Id
惯例,但我在开始使用EF时遇到了同样的问题/疑问。这就是为什么我很快就理解了你的问题,这是一个很好的问题。
CreateTable(
    "MYDB.SYSTEMCONFIGURATION",
    c => new
        {
            ID = c.Decimal(nullable: false, precision: 10, scale: 0)
        })
    .PrimaryKey(t => t.ID)
    .ForeignKey("MYDB.BASESYSTEM", t => t.ID);
CreateTable(
    "MYDB.SYSTEMCONFIGURATION",
    c => new
        {
            ID = c.Decimal(nullable: false, precision: 10, scale: 0, identity: true),
            SYSTEM_ID = c.Decimal(nullable: false, precision: 10, scale: 0),
        })
    .PrimaryKey(t => t.ID)
    .ForeignKey("CISRF.BASESYSTEM", t => t.SYSTEM_ID, cascadeDelete: true);