繁体   English   中英

如何在 Entity Framework Core 中创建一对一关系?

[英]How to create one-to-one relationship in Entity Framework Core?

让我们从一对多关系开始:

public sealed class MyContext : DbContext
{
  protected override void OnModelCreating(ModelBuilder builder)
  {
    builder.Entity<Slave>()
           .HasOne(typeof(Master))
           .WithMany() // *
           .HasForeignKey(nameof(Slave.ForeignField));
  }
}

所以我声明主表中的每一条记录我可以在从表中有多条记录。 当我运行 EF 工具来构建迁移时,这被接受并且工作正常。

但是当我将标有星号的行更改为:

           .WithOne()

为了建立一对一的关系,建立迁移失败并出现错误:

您正在配置“Slave”和“Master”之间的关系,但在“ForeignField”上指定了外键。 必须在作为关系一部分的类型上定义外键。

我不明白,就在一秒钟前,给定的字段(C# 术语中的属性)还可以,现在 EF 声称它找不到它?

我错过了什么? 如何让EF开心?

记录类型如下——请注意没有导航属性。

internal sealed class Slave
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Guid InstanceId { get; set; }

    public Guid ForeignField { get; set; }
}

internal sealed class Master
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Guid Id { get; set; }
}

目前我使用原始 SQL 解决了这个问题,它有效,但我仍然很好奇这里出了什么问题。


感谢@AminGolmahalle 的回答,引发了我的好奇心,为什么以及我可以以通用形式使用HasForeignKey 这让我发现我不能,但更重要的是WithOneWithMany不是彼此的 1:1 替换。 两者都会导致不同的过载。

所以第一个版本的一对多工作是因为我遇到了正确的重载,第二个没有,因为我传递了不正确的参数。 正确的版本是:

builder.Entity<Slave>()
       .HasOne(typeof(Master))
       .WithOne() 
       .HasForeignKey(nameof(Slave), nameof(Slave.ForeignField)); // changed

第一个参数必须是从表的名称(再次)。

但是最好切换到通用版本(请参阅已接受答案下的最后一条评论)并首先避免出现这种“愚蠢”错误的可能性。

下面的代码只是一对一关系的示例:

public class Author
{
    public int AuthorId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public AuthorBiography Biography { get; set; }
}
public class AuthorBiography
{
    public int AuthorBiographyId { get; set; }
    public string Biography { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string PlaceOfBirth { get; set; }
    public string Nationality { get; set; }
    public int AuthorRef { get; set; }
    public Author Author { get; set; }
}

您可以在 EntityFramework 中使用 FluentApi 进行关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Author>()
        .HasOne(a => a.Biography)
        .WithOne(b => b.Author)
        .HasForeignKey<AuthorBiography>(b => b.AuthorRef);
}

使用FluentApiDataAnnotion好得多。

Asp 核心中的 FluentApi

我建议你阅读 FluentValidation

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM