我有两个实体,分别代表Web应用程序的用户和Web应用程序所涉及的播客中的一个参与者。网页的用户具有个人资料,可以登录,可以发表评论等。参与者与他们出现的情节对象相关联,具有传记,图片等。既可以是参与者,也可以是用户同时,但也可能只是用户或参与者。
我正在为EF Core 3.1建模。如果有关系,我还将在该项目中使用.Net Core 3.0,并且数据库为Postgresql(使用Nuget包Npgsql.EntityFrameworkCore.PostgreSQL v3.1.0)。
双方都应为可空/非必需关系。实体非常简单(省略了所有非importart属性):
用户:
public class User
{
public Guid UserId { get; set; }
public Participant Participant { get; set; }
public Guid ParticipantId { get; set; }
}
参与者:
public class Participant
{
public Guid ParticipantId { get; set; }
public User User { get; set; }
public Guid UserId { get; set; }
}
我正在尝试使用Fluent API来配置关系-这似乎是崩溃的地方。
用户配置:
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> user)
{
user.ToTable("users");
user.HasKey(u => u.UserId);
user.HasOne(u => u.Participant)
.WithOne(p => p.User)
.HasForeignKey<Participant>(p => p.UserId);
}
}
参与者配置:
public class ParticipantConfiguration : IEntityTypeConfiguration<Participant>
{
public void Configure(EntityTypeBuilder<Participant> participant)
{
participant.ToTable("participants");
participant.HasKey(p => p.ParticipantId);
participant.HasOne<User>(p => p.User)
.WithOne(u => u.Participant)
.HasForeignKey<User>(u => u.ParticipantId);
}
}
现在,我意识到您应该只配置关系的一侧-至少这就是我解释所读内容的方式。为了完整起见,我仅包括以上内容;我已经尝试过像上面一样一次配置双方,我已经尝试仅在用户端和参与者端进行配置。在每种组合中,代码都会编译,应用程序启动,但是当我尝试通过DbContext将用户实际添加到数据库中时,会遇到相同的异常:
System.InvalidOperationException: 'The child/dependent side could not be determined for the one-to-one relationship between 'Participant.User' and 'User.Participant'. To identify the child/dependent side of the relationship, configure the foreign key property. If these navigations should not be part of the same relationship configure them without specifying the inverse. See http://go.microsoft.com/fwlink/?LinkId=724062 for more details.'
现在,这是两个完全独立的对象,彼此碰巧,因此我不确定孩子/依赖者的心态是否准确,但是我愿意忽略这一细节而屈服于EF Core的意愿。但是,我想不出如何让我的工作无一例外。
TL; DR:
感谢您的见解!
答案 0 :(得分:2)
我认为要做的第一件事是将外键更改为可空值。
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid UserId { get; set; }
public Participant Participant { get; set; }
public Guid? ParticipantId { get; set; }
}
public class Participant
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid ParticipantId { get; set; }
public User User { get; set; }
public Guid? UserId { get; set; }
}
然后保持您的配置完整。我的示例工作配置:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasOne(t => t.Participant)
.WithOne(t => t.User)
.HasForeignKey<Participant>(t => t.UserId);
modelBuilder.Entity<Participant>().HasOne(t => t.User)
.WithOne(t => t.Participant)
.HasForeignKey<User>(t => t.ParticipantId);
base.OnModelCreating(modelBuilder);
}
答案 1 :(得分:1)
我会再次检查是否正在调用您的配置。一切看起来都应该正常工作。