C# 如何在实体框架核心中创建一对一关系?

C# 如何在实体框架核心中创建一对一关系?,c#,entity-framework-core,one-to-one,C#,Entity Framework Core,One To One,让我们从一对多关系开始: public sealed class MyContext : DbContext { protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<Slave>() .HasOne(typeof(Master)) .WithMany() // * .HasForeignKey(na

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

public sealed class MyContext : DbContext
{
  protected override void OnModelCreating(ModelBuilder builder)
  {
    builder.Entity<Slave>()
           .HasOne(typeof(Master))
           .WithMany() // *
           .HasForeignKey(nameof(Slave.ForeignField));
  }
}
为了建立一对一关系,构建迁移失败,出现错误:

您正在配置“从”和“主”之间的关系,但 已在“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 answer,我的好奇心被触发了,为什么我可以使用
HasForeignKey
的通用形式。这让我发现我不能,但更重要的是,一个<代码>和多个<代码>并不是彼此的1:1替代。两者都会导致不同的过载

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

builder.Entity<Slave>()
       .HasOne(typeof(Master))
       .WithOne() 
       .HasForeignKey(nameof(Slave), nameof(Slave.ForeignField)); // changed
builder.Entity()
.HasOne(类型(主))
.WithOne()
.HasForeignKey(nameof(Slave),nameof(Slave.ForeignField));//改变
第一个参数必须是从属表的名称(同样)


但最好切换到通用版本(见“接受答案”下的最后一条评论),并从一开始就避免这种“愚蠢”错误的可能性。

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

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);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity


非常感谢,我无法使用您的解决方案(因为我没有导航属性),但您的代码引发了我的好奇心,为什么您要使用generic
HasForeignKey
。事实证明,
与一个
与多个
一起使用会导致不同的重载。您很好。您需要在模型中编写导航属性。因为您需要使用entityframework从数据库调用数据。没有导航,您无法做到这一点l属性。我知道,但我没有这样的需要。我想要的只是数据完整性,仅此而已。请查看此链接:太好了,它比我的修复程序好,因为它避免了出错的机会。再次感谢您!:-)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Author>()
        .HasOne(a => a.Biography)
        .WithOne(b => b.Author)
        .HasForeignKey<AuthorBiography>(b => b.AuthorRef);
}
Refer this link, i think this will do