我有一个名为 Command 的表
public class Command
{
public int Id { get; set; }
public CommandParameterBaseEntity Parameter { get; set; } = null!;
}
以及两个(或更多)其他具有相同基本类型的表,其中只有一个可以引用 Command。
其他表的基类:
public abstract class CommandParameterBaseEntity
{
public int Id { get; set; }
public int CommandId { get; set; }
public Command Command { get; set; } = null!;
}
派生表:
public class ParameterA : CommandParameterBaseEntity
{
public int SomeValue { get; set; }
}
public class ParameterB : CommandParameterBaseEntity
{
public string AnotherValue { get; set; } = string.Empty;
}
关系:
public class CommandDbCfg
{
public override void Configure(EntityTypeBuilder<Command> builder)
{
builder.ToTable("Command");
builder.HasKey(k => k.Id);
}
}
public abstract class CommandParameterBaseEntityDbCfg<T> : IEntityTypeConfiguration<T> where T : CommandParameterBaseEntity
{
public virtual void Configure(EntityTypeBuilder<T> builder)
{
builder.HasKey(k => k.Id);
builder.HasOne(p => p.Command)
.WithOne(s => s.Parameter as T)
.HasForeignKey<CommandParameterBaseEntity>(p => p.CommandId)
.OnDelete(DeleteBehavior.Cascade);
}
}
public class ParameterADbCfg : CommandParameterBaseEntityDbCfg<ParameterA>
{
public override void Configure(EntityTypeBuilder<ParameterA> builder)
{
builder.ToTable("ParameterA");
base.Configure(builder);
}
}
public class ParameterBDbCfg : CommandParameterBaseEntityDbCfg<ParameterB>
{
public override void Configure(EntityTypeBuilder<ParameterB> builder)
{
builder.ToTable("ParameterB");
base.Configure(builder);
}
}
使用此配置我收到错误:
无法在“ParameterA”上配置密钥,因为它是派生类型。必须在根类型“CommandParameterBaseEntity”上配置密钥。如果您不打算将“CommandParameterBaseEntity”包含在模型中,请确保它不会被上下文中的 DbSet 属性引用,不会在对 ModelBuilder 的配置调用中引用,也不会从包含在模型中的类型上的导航中引用。模型。
是否可以在 efc 中创建这种关系,而无需为命令模型中的每个参数提供导航模型?
我修改了你的代码,因此编译没有错误,创建了 4 个表:
public class CommandDbCfg : IEntityTypeConfiguration<Command>
{
public void Configure(EntityTypeBuilder<Command> builder)
{
builder.ToTable("Command");
builder.HasKey(k => k.Id);
}
}
public class CommandParameterBaseEntityDbCfg<T> : IEntityTypeConfiguration<T> where T : CommandParameterBaseEntity
{
public virtual void Configure(EntityTypeBuilder<T> builder)
{
builder.HasKey(k => k.Id);
builder.HasOne(p => p.Command)
.WithOne(s => s.Parameter as T)
.HasForeignKey<CommandParameterBaseEntity>(p => p.CommandId)
.OnDelete(DeleteBehavior.Cascade);
}
}
public class ParameterADbCfg : IEntityTypeConfiguration<ParameterA>
{
public void Configure(EntityTypeBuilder<ParameterA> builder)
{
builder.ToTable("ParameterA");
}
}
public class ParameterBDbCfg : IEntityTypeConfiguration<ParameterB>
{
public void Configure(EntityTypeBuilder<ParameterB> builder)
{
builder.ToTable("ParameterB");
}
}
...并进入您的 DbContext 类:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
new CommandDbCfg().Configure(modelBuilder.Entity<Command>());
new CommandParameterBaseEntityDbCfg<CommandParameterBaseEntity().Configure(modelBuilder.Entity<CommandParameterBaseEntity>());
new ParameterADbCfg().Configure(modelBuilder.Entity<ParameterA>());
new ParameterBDbCfg().Configure(modelBuilder.Entity<ParameterB>());
base.OnModelCreating(modelBuilder);
}