具有一对一关系和双向属性导航的EF6外键 [英] EF6 Foreign key with one-to-one relationship and two-way property navigation
问题描述
下面是我的类(为简洁起见删除了一些属性):
/ p>
public class BaseSystem
{
public int Id {get;组; }
public SystemConfiguration Configuration {get;组; }
}
public class SystemConfiguration
{
public int Id {get;组; }
public BaseSystem System {get;组; }
}
我想要 SystemConfiguration
表有一个FK引用回到 BaseSystem.Id
。
这是我的流利的API代码: (b)
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ model $ WithOptional(x => x.Configuration);
当我使用双向导航时,会产生这种迁移,
CreateTable(
MYDB.SYSTEMCONFIGURATION,
c => new
{
$ b .PrimaryKey(t => t.ID)
.ForeignKey(b $ b $ ID = c.Decimal(可为空:false,精度:10,scale:0)
} MYDB.BASESYSTEM,t => t.ID);
注意到它生成的SQL不包含FK,我删除了 BaseSystem.Configuration
属性,迁移生成这个:
$ $ $ $ $ $ $ CreateTable(
MYDB.SYSTEMCONFIGURATION,
c => new
{
ID = c.Decimal(可为空,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也生成SYSTEM_ID数字(10,0)not null
如预期的那样,当我有双向导航时,它不会这样做。
我需要做什么来在 SystemConfiguration
表同时仍然有双向导航?
与一对一关系,EF6使用子项中的 Id
列作为父项的FK,它不会创建第二个列,因为这将被视为一对多关系,因为第二列将允许在许多子条目中存在父 Id
,而 PK为FK 不会。
当您移除配置
财产从你的父类,EF6了解你的子类有一个必需的系统
作为父母,但没有任何说它应该是一个t o-one,因此EF6会默认为一对多关系,因为它创建了第二列,这将在许多子条目中允许相同的父项。
有些人可能会争辩说,可以为第二个
列创建一个唯一索引作为FK以避免拥有相同的父ID,但EF6不会这样工作
(也许他们认为这样做没有意义)。
您尝试的第一个选项是配置一对一关系的正确方法, SystemConfiguration
中的 Id
是PK和FK到 BaseSystem
在同一时间。
I cannot seem to get EF6 to generate a FK when I am using two-way navigation.
Here are my classes (removed some properties for brevity):
public class BaseSystem
{
public int Id { get; set; }
public SystemConfiguration Configuration { get; set; }
}
public class SystemConfiguration
{
public int Id { get; set; }
public BaseSystem System { get; set; }
}
I want the SystemConfiguration
table to have a FK reference back to BaseSystem.Id
.
Here's my fluent API code:
modelBuilder.Entity<SystemConfiguration>()
.HasRequired(x => x.System)
.WithOptional(x => x.Configuration);
When I use two-way navigation, this migration is generated which seems to generate the FK at first:
CreateTable(
"MYDB.SYSTEMCONFIGURATION",
c => new
{
ID = c.Decimal(nullable: false, precision: 10, scale: 0)
})
.PrimaryKey(t => t.ID)
.ForeignKey("MYDB.BASESYSTEM", t => t.ID);
After noticing that the SQL it generates doesn't include the FK, I removed the BaseSystem.Configuration
property and the migration generates this:
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);
My SQL also generates "SYSTEM_ID" number(10, 0) not null
as expected which it does not do when I have two-way nav.
What do I need to do to generate the FK on the SystemConfiguration
table while also still having two-way navigation?
When working with one-to-one relationship, EF6 uses the Id
column in the child as the FK to the parent, it won't create a second column for FK because that would be considered one-to-many relationship, because that second column would allow a parent Id
to exist in many child entries, whereas the PK as FK wouldn't.
When you removed the Configuration
property from your parent class, EF6 understood your child class had a required System
as parent, but there was nothing saying it should be one-to-one, so EF6 would treat as a one-to-many relationship by default, since it created that second column, which would allow the same parent in many child entries.
Some may argue you could create a unique index for that second column as FK to avoid having the same parent id, but EF6 doesn't work this way (maybe they think it doesn't make sense doing this).
The first option you tried is the right way to configure a one-to-one relationship, and the Id
in the SystemConfiguration
is a PK and a FK to BaseSystem
at the same time.
这篇关于具有一对一关系和双向属性导航的EF6外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!