【问题标题】:EF code first - configure One-to-Zero-or-One relationship without shared PK/FKEF 代码优先 - 配置一对零或一关系,无需共享 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 属性?

干杯!

【问题讨论】:

    标签: c# sql-server entity-framework


    【解决方案1】:

    不支持具有显式 FK 属性的双向 one-to-one 关系。

    所以要么继续使用你现在拥有的 - Shared Primary Key association。只需从Task 中删除TaskIdFileId 属性之一,并将剩余的属性设为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 JOINs,正如你可以看到的那样发布EF - WithOptional - Left Outer Join?

    【讨论】:

    • 非常感谢,很好的回答:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 2015-07-29
    • 2013-07-03
    • 1970-01-01
    相关资源
    最近更新 更多