将一个表引用到“多个”表中的一个表

问题描述 投票:0回答:1

我有一个名为 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 中创建这种关系,而无需为命令模型中的每个参数提供导航模型?

c# entity-framework entity-framework-core ef-code-first-mapping
1个回答
0
投票

我修改了你的代码,因此编译没有错误,创建了 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.