这是两个课程的关键部分:
public class User
{
public int Id { get; set; }
public required ICollection<Skill> SelfIdentifiedSkills { get; set; }
public required ICollection<Skill> CertifiedSkills { get; set; }
}
public class Skill
{
public int Id { get; set; }
public required ICollection<User> CertifiedUsers { get; set; }
public required ICollection<User> SelfIdentifiedUsers { get; set; }
}
当我运行
Add-Migration
我得到:
无法确定类型为“ICollection”的导航“Skill.CertifiedUsers”所代表的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。
我知道在 User 中有两个相同类型的集合有点奇怪。但并没有那么不寻常。无论如何,我怎样才能让它工作?最好使用流利的命令(而不是属性)。
您可以通过为任一实体注册一个实体配置来解决这个问题,您可以在其中声明该实体的哪个属性以何种方式与另一个实体的属性相关。
在这种情况下,由于用户可能更依赖于技能,反之亦然,我们将制作一个
UserConfiguration
:
using Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Infrastructure.Data.PostgreSql.Configurations
{
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> user)
{
user.HasMany(user => user.SelfIdentifiedSkills)
.WithMany(skill => skill.SelfIdentifiedUsers);
user.HasMany(user => user.CertifiedSkills)
.WithMany(skill => skill.CertifiedUsers);
}
}
}
然后在您的
Context
课程中,您在 OnModelCreating
期间应用配置。您可以显式地为该配置执行此操作,或者告诉上下文在给定程序集中查找所有配置类。
using Domain.Entities;
using Infrastructure.Data.PostgreSql.Configurations;
using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Data.PostgreSql
{
public class DataContext : DbContext
{
// Properties
public DbSet<User> Users => Set<User>();
public DbSet<Skill> Skills => Set<Skill>();
// Constructors
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
// Methods
protected override void OnModelCreating(ModelBuilder model)
{
// Either
model.ApplyConfiguration(new UserConfiguration());
// Or
model.ApplyConfigurationsFromAssembly(typeof(DataContext).Assembly);
}
}
}