Entity Core FluentAPI - 作为主键和外键的 ID

Entity Core FluentAPI - An ID as Primary and Foreign Key

我有两个实体 UserProfile。这些实体中的每一个都继承自包含 Id 属性 的 Entity class。用户和配置文件之间的关系是一对一的关系。我正在尝试使用为用户实体创建的相同 Id 作为配置文件实体的 Id,即 User.Id == Profile.Id.

我一直在尝试使用 FluentAPI 执行此操作,但我做不到。我已经阅读了这个 and also read this post,但我仍然无法找到解决问题的方法。

这是我的实体的代码:

public class Entity<TKey> : IEntity
{
    /// <summary>
    /// Unique identifier for this entity.
    /// </summary>
    public virtual int Id { get; set; }
}

public class User : Entity<int>
{
    public virtual Profile ProfileItem { get; set; }
}

public class Profile : Entity<int> 
{

}

这是我迄今为止的试验,其中全部失败:

正如我之前提到的问题中所报告的,此问题的唯一解决方案是您必须添加一个逆 属性,然后使用数据注释。我尝试了以下方法并且有效:

public class Entity<TKey> : IEntity
{
    /// <summary>
    /// Unique identifier for this entity.
    /// </summary>
    public virtual int Id { get; set; }
}

public class User : Entity<int>
{
    [InverseProperty("User")]
    public virtual Profile ProfileItem { get; set; }
}

public class Profile : Entity<int> 
{
    [ForeignKey("Id")]
    public virtual User User { get; set; }
}

如何使它与 FluentAPI 一起工作?

@Ivan 说的对。在我发布的示例中,我在 OnModelCreating 事件上进行了映射,但在我的实际代码中,我使用了基数 class 进行映射,这就是问题所在。

这是我当前产生问题的代码:

  • 实体映射的基础class

    public class EntityTypeConfigurationBase<T> : IEntityTypeConfiguration<T> where T : class, IEntity
    {
        private bool BIgnoreBaseProps = true;
    
        public EntityTypeConfigurationBase(bool bIgnoreBaseProps = true) : base()
        {
            BIgnoreBaseProps = bIgnoreBaseProps;
        }
    
        public void Configure(EntityTypeBuilder<T> builder)
        {
            if (BIgnoreBaseProps)
            {
                builder.Ignore(x => x.State);
                builder.Ignore(x => x.AssociationState);
            }
        }
    }
    
  • 我的映射class

    public class UserMap : EntityTypeConfigurationBase<User>
    {
    
       new public void Configure(EntityTypeBuilder<User> builder)
       {
    
        builder.HasKey(u => u.Id);
        builder
            .HasOne(u => u.ProfileItem)
            .WithOne()
            .HasForeignKey<Profile>(p => p.Id)
            .IsRequired()
            .OnDelete(DeleteBehavior.Cascade);
        builder.ToTable("User");
    
        base.Configure(builder);
        }
    }
    

问题出在 Configure 方法中的映射 class 中。在基础 class 中,我需要忽略一些共享属性,而在映射 classes 中,我需要进行自定义映射。使用的方法名为 Configure,映射需要实现该方法。由于相同的方法名称用于基础和派生 classes,这导致了重复调用。第一次调用是针对基本类型方法,第二次是针对映射 classes。映射了两次,外键(我的问题)是在第一次映射时生成的。

此问题的解决方案是将基类型方法标记为 virtual,然后覆盖基类型上的方法。基本类型方法调用将采用相同的 ModelBuilder 对象,不会再次复制映射。