C# 实体框架核心中的一对一关系
在过去的几周里,我一直在使用.NETCore,并决定尝试EFCore(来自NHibernate的ASP.NETMVC)。经过一番挖掘,我发现了一个很好的扩展名为。它允许我直观地创建模型并生成代码 我定义了一个简单的一对一关系,如图所示: 生成代码后,我得到以下Fluent API代码:C# 实体框架核心中的一对一关系,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,在过去的几周里,我一直在使用.NETCore,并决定尝试EFCore(来自NHibernate的ASP.NETMVC)。经过一番挖掘,我发现了一个很好的扩展名为。它允许我直观地创建模型并生成代码 我定义了一个简单的一对一关系,如图所示: 生成代码后,我得到以下Fluent API代码: modelBuilder.Entity<Authentication>() .ToTable("Authentications") .HasKey(t => t.Id); mod
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();
身份验证具有以下(相关)属性:
[Key]
[Required]
public Guid Id { get; set; }
但是,当我尝试生成迁移时,会出现以下错误:
您正在配置“用户”和“身份验证”之间的关系
但已在上指定了外键
“身份验证Id”。外键
必须在作为关系一部分的类型上定义
我试着切换到多对一的关系,这没有任何问题。这可能是一个工作,但不是一个非常干净的。这是否可能是由于命名问题,例如两个实体都以“Id”作为主键
如果是这样,“最佳实践”是什么?我是否为每个实体指定了唯一的ID列名?如何处理派生类都继承ID列的抽象实体?您需要将外键放在另一个类上。您的身份验证类似乎没有属性“Authentication\u Id”。您需要将外键放在另一个类上。您在身份验证类上似乎没有属性“Authentication\u Id”。我从未使用EF Visual Designer生成代码,但仅通过查看您的代码,
用户
实体需要身份验证
的外键,或者身份验证
实体需要用户的外键
假设您想将外键放入User
:
公共类用户
{
[关键]
[必需]
公共Guid Id{get;set;}
公共Guid身份验证ID{get;set;}
//甚至这个导航属性也是可选的
//用于配置一对一关系
公共虚拟身份验证{get;set;}
}
公开认证
{
[关键]
[必需]
公共Guid Id{get;set;}
}
然后,一对一关系应配置为:
modelBuilder.Entity()
.HasOne(x=>x.Authentication)
//如果您没有身份验证导航属性,请执行以下操作:
//.HasOne()
.WithOne()
.HasForeignKey(x=>x.AuthenticationId);
不,您不必为每个实体指定唯一的ID列名。事实上,您可以调用代码中的任何内容,并在配置中重命名它:
modelBuilder.Entity()
.Property(x=>x.Id).HasColumnName(“无论您想在数据库中调用什么”);
我从未使用EF Visual Designer生成代码,但仅通过查看您的代码,用户
实体需要身份验证
的外键,或者身份验证
实体需要用户
的外键
假设您想将外键放入User
:
公共类用户
{
[关键]
[必需]
公共Guid Id{get;set;}
公共Guid身份验证ID{get;set;}
//甚至这个导航属性也是可选的
//用于配置一对一关系
公共虚拟身份验证{get;set;}
}
公开认证
{
[关键]
[必需]
公共Guid Id{get;set;}
}
然后,一对一关系应配置为:
modelBuilder.Entity()
.HasOne(x=>x.Authentication)
//如果您没有身份验证导航属性,请执行以下操作:
//.HasOne()
.WithOne()
.HasForeignKey(x=>x.AuthenticationId);
不,您不必为每个实体指定唯一的ID列名。事实上,您可以调用代码中的任何内容,并在配置中重命名它:
modelBuilder.Entity()
.Property(x=>x.Id).HasColumnName(“无论您想在数据库中调用什么”);
那么将Id属性重命名为Authentication\u Id可以修复它吗?是的。或者您将HasForeignKey()
调用更改为类似于HasForeginKey(x=>x.Id)
。因此将Id属性重命名为Authentication\u Id可以修复它吗?是的。或者您可以将HasForeignKey()
调用更改为类似于HasForeginKey(x=>x.Id)
。
[Key]
[Required]
public Guid Id { get; set; }