我有两个实体User
和Profile
。每个实体都继承自Entity
类,其中包含Id
属性。用户和个人资料之间的关系是一对一的关系。我正在尝试使用为User实体创建的相同Id作为Profile实体的Id,即User.Id == Profile.Id
。
我一直试图用FluentAPI做到这一点,但我无法做到。我已阅读此question并阅读此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>
{
}
到目前为止,我的审判都失败了:
此映射在ProfileItemId
表中生成User
:
modelBuilder.Entity<User>().HasOne(u => u.ProfileItem)
.WithOne()
.HasForeignKey<Profile>(p => p.Id)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
我尝试在Profile
实体中为User
添加反向导航属性。 User
表已正确映射,但UserId
表中添加了Profile
列:
modeBuilder.Entity<User>().HasOne(u => u.ProfileItem)
.WithOne(u => u.User)
.HasForeignKey<Profile>(p => p.Id)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
我之前提到的问题中报告的唯一解决此问题的方法是,您必须添加反向属性,然后使用数据注释。我尝试了以下内容并且有效:
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?
答案 0 :(得分:0)
@Ivan说的是对的。在我发布的示例中,我在OnModelCreating事件上进行了映射,但在我的实际代码中,我使用了基类进行映射,这就是问题所在。
这是我当前产生问题的代码:
实体映射的基类
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);
}
}
}
我的映射类
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方法中。在基类中,我需要忽略一些共享属性,在映射类中,我需要进行自定义映射。使用的方法名为Configure
,需要为映射实现。由于同一方法名称用于基类和派生类,因此导致重复调用。第一个调用是基类型方法,第二个调用是映射类。映射完成了两次,并在第一个映射上生成了外键(我的问题)。
此问题的解决方案是将基类型方法标记为virtual
,然后覆盖基类型上的方法。基类型方法调用将采用相同的ModelBuilder
对象,并且不会再次复制映射。