c# - Entity Framework Core 中的一对一关系

标签 c# entity-framework entity-framework-core

过去几周我一直在玩 .NET Core,并决定尝试 EF Core(来自 ASP.NET MVC 和 NHibernate)。经过一番挖掘,我发现了一个不错的扩展名为 EF Visual Designer .它使我能够直观地创建模型并生成代码。
我已经定义了一个简单的一对一关系,如图所示:
Simple one-to-one relationship
生成代码后,我得到以下 Fluent API 代码:

modelBuilder.Entity<Authentication>()
   .ToTable("Authentications")
   .HasKey(t => t.Id);

modelBuilder.Entity<Authentication>()
    .Property(t => t.Id)
    .IsRequired()
    .ValueGeneratedOnAdd();

modelBuilder.Entity<User>()
     .ToTable("Users")
     .HasKey(t => t.Id);

modelBuilder.Entity<User>()
     .Property(t => t.Id)
     .IsRequired()
     .ValueGeneratedOnAdd();

modelBuilder.Entity<User>()
    .HasOne(x => x.Authentication)
    .WithOne()
    .HasForeignKey("Authentication_Id")
    .IsRequired();
用户类具有以下(相关)属性:
public Class User {
    [Key]
    [Required]
    public Guid Id { get; set; }
    ...
    public virtual Authentication Authentication { get; set; }
}
身份验证具有以下(相关)属性:
public class Authentication  {
    [Key]
    [Required]
    public Guid Id { get; set; }
}
但是,当我尝试生成迁移时,出现以下错误:

You are configuring a relationship between 'User' and 'Authentication' but have specified a foreign key on 'Authentication_Id'. The foreign key must be defined on a type that is part of the relationship.


我尝试切换到多对一的关系,并且没有任何问题。这可能是一种解决方法,但不是一个非常干净的方法。这可能是由于命名问题,例如两个实体都将“Id”作为主键?
如果是这种情况,“最佳实践”是什么?我是否给每个实体一个唯一的 ID 列名称?我如何处理具有所有继承 ID 列的派生类的抽象实体?

最佳答案

我从未使用 EF Visual Designer 生成代码,只是通过查看您的代码,User实体需要Authentication的外键, 或 Authentication实体需要User的外键.
假设您想将外键放入 User :

public class User
{
    [Key]
    [Required]
    public Guid Id { get; set; }

    public Guid AuthenticationId { get; set; }

    // Even this navigation property is optional
    // for configuring one-to-one relationship
    public virtual Authentication Authentication { get; set; }
}

public class Authentication
{
    [Key]
    [Required]
    public Guid Id { get; set; }
}
那么一对一的关系应该配置为:
modelBuilder.Entity<User>()
    .HasOne(x => x.Authentication)

    // Or like this if you don't have Authentication navigation property:
    //.HasOne<Authentication>()

    .WithOne()
    .HasForeignKey(x => x.AuthenticationId);
不,您不必为每个实体提供唯一的 ID 列名称。实际上,您可以在代码中调用任何内容并在配置中重命名它:
modelBuilder.Entity<User>()
    .Property(x => x.Id).HasColumnName("WHATEVER_YOU_WANT_TO_CALL_IN_DB");

关于c# - Entity Framework Core 中的一对一关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55205049/

相关文章:

c# - 具有非标准命名约定的数据库的 POCO 别名

c# - EF : The instance of entity type X cannot be tracked because another instance of this type with the same key is already being tracked

c# - 如何控制 EF Core 运行自定义迁移的顺序?

c# - 如何使用 C# MongoDB.Driver 更新深层嵌套数组?

c# - 如何从 WinForms 中的 app.config 读取 AppSettings

c# - ToList() 与 EF4 的高锁争用和低性能

c# - asp.net mvc 中的 LINQ + EntityFunctions

c# - 使用自定义表达式扩展 EF Core 'where' 子句

c# - 使用 log4net 记录时“等待”不返回 UI 线程

c# - 将资源从 c# pjct 复制到 Windows 目录