EF 代码优先 - 配置一对零或一关系,无需共享 PK/FK
Posted
技术标签:
【中文标题】EF 代码优先 - 配置一对零或一关系,无需共享 PK/FK【英文标题】:EF code first - configure One-to-Zero-or-One relationship without shared PK/FK 【发布时间】:2017-05-24 16:45:33 【问题描述】:我正在尝试在两个实体之间建立一对零或一的关系,并且我希望依赖实体仍包含其自己的 Indentity 列,而不是共享键。
我想尽可能地遵循约定,并且不明确声明任何不需要明确声明的内容(因此,没有不必要的数据注释或流畅的 api 子句)
实体:
public class File
public int FileId get;set;
//some omitted file properties
public virtual Task Task get;set;
public class Task
public int TaskId get;set;
//some omitted task properties
public int FileId get;set;
public virtual File File get;set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<File>().HasOptional(f => f.Task).WithRequired(t => t.File);
base.OnModelCreating(modelBuilder);
这会创建一个奇怪的关系,其中 TaskId 是 Tasks 表的 PK 和 FK 列。我认为这意味着它应该与文件 ID 具有相同的值? (这是一个问题:))
那么,如何让 TaskId 拥有自己的顺序值,并使 FileId 成为 Files 表的外键?
或者也许在 1-0..1 的情况下,我宁愿摆脱 TaskId 属性并让 FileId 成为 PK/FK 属性?
干杯!
【问题讨论】:
【参考方案1】:不支持具有显式 FK 属性的双向 one-to-one
关系。
所以要么继续使用你现在拥有的 - Shared Primary Key association。只需从Task
中删除TaskId
或FileId
属性之一,并将剩余的属性设为PK(EF 将自动将其用作FK,因为这是默认的EF one-to-one
关系模型)。
或者去掉Task
中的FieldId
属性,使用如下流畅的配置(都是必须的):
modelBuilder.Entity<File>()
.HasOptional(f => f.Task)
.WithRequired(t => t.File)
.Map(m => m.MapKey("FileId"))
.WillCascadeOnDelete();
但我建议使用第一种方法(如果没有特殊原因不这样做,就像现有数据库等一样),因为它得到更好的支持 - 第二种方法在 SQL 查询中包含一些 LEFT OUTER JOIN
s,正如你可以看到的那样发布EF - WithOptional - Left Outer Join?。
【讨论】:
非常感谢,很好的回答:)以上是关于EF 代码优先 - 配置一对零或一关系,无需共享 PK/FK的主要内容,如果未能解决你的问题,请参考以下文章