如何在 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));
}
}
所以我声明在 Master table 中每条记录我可以在 Slave table 中有多个记录。当我 运行 EF 工具构建迁移时,这被接受并且工作正常。
但是当我将标有星号的行更改为:
.WithOne()
为了建立一对一的关系,建立迁移失败并出现错误:
You are configuring a relationship between 'Slave' and 'Master' but
have specified a foreign key on 'ForeignField'. The foreign key must
be defined on a type that is part of the relationship.
我不明白,就在一秒钟前给定的字段(属性 在 C# 术语中)是好的,现在 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
。这让我发现我做不到,但更重要的是 WithOne
和 WithMany
不是 1:1 彼此的替代品。两者都会导致不同的过载。
所以第一个版本的一对多工作是因为我遇到了正确的重载,第二个没有,因为我传递了不正确的参数。正确的版本是:
builder.Entity<Slave>()
.HasOne(typeof(Master))
.WithOne()
.HasForeignKey(nameof(Slave), nameof(Slave.ForeignField)); // changed
第一个参数必须是奴隶的名字table(再次)。
但是最好切换到通用版本(请参阅已接受答案下的最后评论)并首先避免出现此类 "stupid" 错误的可能性。
下面的代码只是一对一关系的示例:
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);
}
使用 FluentApi 比 DataAnnotaion 好得多。
Refer this link, i think this will do
https://www.learnentityframeworkcore.com/configuration/one-to-one-relationship-configuration
让我们从一对多关系开始:
public sealed class MyContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Slave>()
.HasOne(typeof(Master))
.WithMany() // *
.HasForeignKey(nameof(Slave.ForeignField));
}
}
所以我声明在 Master table 中每条记录我可以在 Slave table 中有多个记录。当我 运行 EF 工具构建迁移时,这被接受并且工作正常。
但是当我将标有星号的行更改为:
.WithOne()
为了建立一对一的关系,建立迁移失败并出现错误:
You are configuring a relationship between 'Slave' and 'Master' but have specified a foreign key on 'ForeignField'. The foreign key must be defined on a type that is part of the relationship.
我不明白,就在一秒钟前给定的字段(属性 在 C# 术语中)是好的,现在 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
。这让我发现我做不到,但更重要的是 WithOne
和 WithMany
不是 1:1 彼此的替代品。两者都会导致不同的过载。
所以第一个版本的一对多工作是因为我遇到了正确的重载,第二个没有,因为我传递了不正确的参数。正确的版本是:
builder.Entity<Slave>()
.HasOne(typeof(Master))
.WithOne()
.HasForeignKey(nameof(Slave), nameof(Slave.ForeignField)); // changed
第一个参数必须是奴隶的名字table(再次)。
但是最好切换到通用版本(请参阅已接受答案下的最后评论)并首先避免出现此类 "stupid" 错误的可能性。
下面的代码只是一对一关系的示例:
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);
}
使用 FluentApi 比 DataAnnotaion 好得多。
Refer this link, i think this will do
https://www.learnentityframeworkcore.com/configuration/one-to-one-relationship-configuration