[英]EF6 One-To-One relationship with separate ID property
我们需要在以下实体之间定义一对一关系:
public class Foo
{
[Key, Column("Foo_ID")]
public int Id { get; set; }
public Bar Bar { get; set; }
}
public class Bar
{
[Key, Column("Bar_ID")]
public int Id { get; set; }
[Column("Bar_Foo_ID")]
public int? FooId { get; set; }
public Foo Foo { get; set; }
}
我们需要迁移旧版软件,并让它们现在并排运行。 所以我们不能改变任何关系。 遗憾的是,数据库中没有定义外键。
modelBuilder.Entity<Foo>()
.HasOptional(a => a.Bar)
.WithRequired(x => x.Foo)
.WillCascadeOnDelete(true);
当我们查询Foo
和Include(x => x.Bar)
它会创建一个带有LEFT OUTER JOIN bars ON Foo_ID = Bar_ID
的SQL查询LEFT OUTER JOIN bars ON Foo_ID = Bar_ID
这是错误的。
我们需要LEFT OUTER JOIN bars on Foo_ID = Bar_Foo_ID
其更改为LEFT OUTER JOIN bars on Foo_ID = Bar_Foo_ID
,但我不确定Entity Framework是如何支持的,因为我们的DB和Bar_ID
没有外键作为PrimaryKey。
我知道一个Foo
可能有多个Bars
,但是有没有办法强制实现一对一关系?
创建Foo
,始终会为其创建一个Bar
。
对于旧数据,您可以使用以下内容:
1:0-1关系基本上是1:许多关系的特殊形式。
因此,您可以在实体框架中将关系配置为1:many,并可能向外键属性添加唯一索引,以强制执行max的约束。 一个相关的条目。
public class Foo
{
[Key, Column("Foo_ID")]
public int Id { get; set; }
// this can't be a single reference property unfortunately... but it will only contain 0 or 1 object when working with it.
public ICollection<Bar> Bars { get; set; }
}
public class Bar
{
[Key, Column("Bar_ID")]
public int Id { get; set; }
[Index(IsUnique = true)]
[Column("Bar_Foo_ID")]
public int? FooId { get; set; }
public Foo Foo { get; set; }
}
modelBuilder.Entity<Foo>()
.HasMany(a => a.Bars)
.WithRequired(x => x.Foo)
.HasForeignKey(x => x.FooId)
.WillCascadeOnDelete(true);
我理解它的方式,你在Bar
表中有一个名为Bar_Foo_ID
的现有列,它必须用作Bar
表中PK Bar_ID
列的FK。
这是可能的,但EF6对这种关系的支持有限,特别是不支持显式FK属性。 所以你必须从模型中删除FooId
属性:
public class Bar
{
[Key, Column("Bar_ID")]
public int Id { get; set; }
public Foo Foo { get; set; }
}
并使用以下流畅的配置:
modelBuilder.Entity<Foo>()
.HasOptional(a => a.Bar)
.WithOptionalPrincipal(x => x.Foo)
.Map(m => m.MapKey("Bar_Foo_ID"))
.WillCascadeOnDelete(true);
MapKey
是指定FK列名。 WithOptionalPrincipal
用于指定它可以为空(而WithRequired
用于非可空)。
请注意,对于可选关系,EF6会以不同方式处理级联删除。 它不是删除相关记录,而是通过将FK设置为null
来取消它们。 如果您想在删除Foo
时实际删除关联的Bar
,则必须使用代码手动执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.