gpt4 book ai didi

c# - 如何定义两个实体之间的多重关系?

转载 作者:行者123 更新时间:2023-11-30 12:21:04 25 4
gpt4 key购买 nike

我有一个用户可以上传多张照片(一对多)的场景。 用户还可以拥有默认照片(一对一)。但是,我的 Entity Framework core 2.0告诉我,当我使用下面的代码时,他无法识别这种关系:

public class User
{
public Guid Id { get; set; }

public ICollection<Photo> Photos{ get; set; }

public Photo DefaultPhoto { get; set; }
[ForeignKey("DefaultPhoto")]
public Guid DefaultPhotoId { get; set; }
}

public class Photo
{
public Guid Id { get; set; }

public User Owner { get; set; }
}

我怎样才能实现这些多重关系?

EF-Core 显示错误:

System.InvalidOperationException: 'Unable to determine the relationship represented by navigation property 'Photo.Owner' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.'

更新:

[InverseProperty("Photos")] 添加到文件模型中的导航属性 Owner 似乎有效。我不确定这是否是正确的方法?

enter image description here在此图像中 File=Photo; Uploader=Owner(与上述模型相比较)。

更新 2:

我确认@Ivan 在评论中所说的内容,通过 DataAnnotation 方法,我在两个方向上获得了一对多,而不是一对多和一对一。此图显示了使用 InverseProperty 生成的数据库(to 实体之间的连接显示双向一对多关系):

enter image description here

在此图像中 File=Photo; Uploader=Owner(与上述模型相比较)。

最佳答案

使用 Fluent API 建立一对一关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Establish a one to one relationship with the
// User as the dependent End
modelBuilder.Entity<User>()
.HasOne(u => u.DefaultPhoto)
.WithOne(p => p.Owner)
.HasForeignKey<User>(u => u.DefaultPhotoId);
}

要使关系成为一对一 (1:0..1) 关系,必须在两个主键或两个候选键之间建立关系。 (查看 this blog post 了解更多信息。)

EF 目前无法通过注释设置候选键(也称为唯一键或备用键),因此这是您唯一的选择。在 Microsoft Docs 查看 EF 文档:One to One relationships


更新:早期的代码会自动生成一个 UserId 列并正确设置关系。我已将 OwnerId 字段添加到 Photo 实体以手动设置关系,如您所愿:

public class User
{
public Guid Id { get; set; }

[InverseProperty("Owner")]
public ICollection<Photo> Photos{ get; set; }

public Photo DefaultPhoto { get; set; }
public Guid DefaultPhotoId { get; set; }
}

public class Photo
{
public Guid Id { get; set; }

public Guid OwnerId { get; set; }
public User Owner { get; set; }
}

public class MyDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Photo> Photos { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// You may use this instead of the inverse property
// // The One to Many relationship between
// // User.Id (Principal End) and Photo.OwnerId
// modelBuilder.Entity<Photo>()
// .HasOne(p => p.Owner)
// .WithMany(u => u.Photos)
// .HasForeignKey(p => p.OwnerId);

// Establishes 1:0..1 relationship between
// Photo.Id (Principal End) and User.DefaultPhoto (Dependent end)
modelBuilder.Entity<User>()
.HasOne(u => u.DefaultPhoto)
.WithOne() // we leave this empty because it doesn't correspond to a navigation property in the Photos table
.HasForeignKey<User>(u => u.DefaultPhotoId);
}
}

诀窍在于确定关系(尤其是主要端和从属端)以及确定哪些需要导航属性。

Inverse 属性是必需的,因为 EF 不知道要将哪个属性映射到 Photo.Owner。这只是在此类情况下明确关系的一种方式。

关于c# - 如何定义两个实体之间的多重关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47728331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com