EF Core:全局查询过滤器导致为基本类型创建表

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

假设我有以下实体:

public abstract class BaseClass
{
    public int Id { get; set; }
    public string BaseProperty { get; set; }
}

public class ChildClassOne : BaseClass
{
    public string PropertyOne { get; set; }
}

public class ChildClassTwo : BaseClass
{
    public string PropertyTwo { get; set; }
}

及型号配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<ChildClassOne>().ToTable("ChildsOne");
    modelBuilder.Entity<ChildClassTwo>().ToTable("ChildsTwo");
}

从上面的实体和配置生成的迁移仅创建两个表,省略了基本类型的表。

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "ChildsOne",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            PropertyOne = table.Column<string>(type: "TEXT", nullable: false),
            BaseProperty = table.Column<string>(type: "TEXT", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_ChildsOne", x => x.Id);
        });

    migrationBuilder.CreateTable(
        name: "ChildsTwo",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            PropertyTwo = table.Column<string>(type: "TEXT", nullable: false),
            BaseProperty = table.Column<string>(type: "TEXT", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_ChildsTwo", x => x.Id);
        });
}

但是,添加全局查询过滤器后:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // Global Query Filter
    modelBuilder.Entity<BaseClass>().HasQueryFilter(x => x.Id == x.Id);

    modelBuilder.Entity<ChildClassOne>().ToTable("ChildsOne");
    modelBuilder.Entity<ChildClassTwo>().ToTable("ChildsTwo");
}

此添加后生成的迁移会为基本类型创建一个表。

protected override void Up(MigrationBuilder migrationBuilder)
{
    // HERE: Table for the base class is being created
    migrationBuilder.CreateTable(
        name: "BaseClass",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            BaseProperty = table.Column<string>(type: "TEXT", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_BaseClass", x => x.Id);
        });

    migrationBuilder.CreateTable(
        name: "ChildsOne",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            PropertyOne = table.Column<string>(type: "TEXT", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_ChildsOne", x => x.Id);
            table.ForeignKey(
                name: "FK_ChildsOne_BaseClass_Id",
                column: x => x.Id,
                principalTable: "BaseClass",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
        });

    migrationBuilder.CreateTable(
        name: "ChildsTwo",
        columns: table => new
        {
            Id = table.Column<int>(type: "INTEGER", nullable: false)
                .Annotation("Sqlite:Autoincrement", true),
            PropertyTwo = table.Column<string>(type: "TEXT", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_ChildsTwo", x => x.Id);
            table.ForeignKey(
                name: "FK_ChildsTwo_BaseClass_Id",
                column: x => x.Id,
                principalTable: "BaseClass",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
        });
}

是否可以应用全局查询过滤器而无需为基本类型创建表?

c# entity-framework-core
1个回答
0
投票

您可以在每个表上指定它:

modelBuilder.Entity<ChildClassOne>()
    .ToTable("ChildsOne")
    .HasQueryFilter(x => x.Id == x.Id);
modelBuilder.Entity<ChildClassTwo>()
    .ToTable("ChildsTwo")
    .HasQueryFilter(x => x.Id == x.Id);

或者,您可以尝试设置 Table-per-concrete-type 配置(未测试):

modelBuilder.Entity<BaseClass>()
    .UseTpcMappingStrategy()
    .HasQueryFilter(x => x.Id == x.Id);

modelBuilder.Entity<ChildClassOne>().ToTable("ChildsOne");
modelBuilder.Entity<ChildClassTwo>().ToTable("ChildsTwo");
© www.soinside.com 2019 - 2024. All rights reserved.