0

我正在开发一个需要实体可扩展性而无需更改基本实体的项目。我有一个包含基本模型的 DLL 和一个包含模型扩展的 DLL(包括对基本模型项目的引用)。基本模型包含在具有相应 DbContextMain 的项目中。扩展包含在另一个项目中,带有它们的 DBContextExtensions。

这是基本模型,在基本模型 DLL 中:

    public class Person : BaseEntity
    {
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public DateTimeOffset DateOfBirth { get; set; }

        // plus other nested entities hot shown here for simplification
    }

, 在哪里:

    public class BaseEntity
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public long Id { get; set; }

        public bool IsDeleted { get; set; }
    }

,并且在我的扩展 DLL 中:

public class PersonExtension : BaseEntity
    {
        public long PersonId { get; set; }

        // reference to the extended model
        [ForeignKey(nameof(PersonId))]
        public Person Person { get; set; }

        // extension fields for Person type
        public decimal Height { get; set; }
        public decimal Weight { get; set; }
    }

现在,我为基本模型创建了一个带有 DbContext 的项目 MainModels:

public class ApplicationDataContextMain : BaseDataContext
    {
        // base models only
        public DbSet<Person> Persons { get; set; }
    }

,如果我添加迁移,它会按预期创建迁移:

...
            migrationBuilder.CreateTable(
                name: "Persons",
                columns: table => new
                {
                    Id = table.Column<long>(type: "bigint", nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
                    FirstName = table.Column<string>(type: "text", nullable: true),
                    MiddleName = table.Column<string>(type: "text", nullable: true),
                    LastName = table.Column<string>(type: "text", nullable: true),
                    DateOfBirth = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false)
                }
...

如果我只为扩展实体创建带有 DbContext 的 ExtensionModels 项目:

public class ApplicationDataContextExtensions : BaseDataContext
    {
        // extensions to models only
        public DbSet<PersonExtension> PersonExtensions { get; set; }
    }

,然后我添加迁移,它将添加 Persons 表和 PersonExtensions 表:

...
// vvv I WANT TO GET RID OF THIS vvv
            migrationBuilder.CreateTable(
                name: "Persons",
                columns: table => new
                {
                    Id = table.Column<long>(type: "bigint", nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
                    FirstName = table.Column<string>(type: "text", nullable: true),
                    MiddleName = table.Column<string>(type: "text", nullable: true),
                    LastName = table.Column<string>(type: "text", nullable: true),
                    DateOfBirth = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false)
                }
// plus the other models in the base models DLL
// ^^^ UNTIL HERE ^^^
...
            migrationBuilder.CreateTable(
                name: "PersonExtensions",
                columns: table => new
                {
                    Id = table.Column<long>(type: "bigint", nullable: false)
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
                    PersonId = table.Column<long>(type: "bigint", nullable: false),
                    Height = table.Column<decimal>(type: "numeric", nullable: false),
                    Weight = table.Column<decimal>(type: "numeric", nullable: false),
                    IsDeleted = table.Column<bool>(type: "boolean", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_PersonExtensions", x => x.Id);
// vvv BUT KEEP THIS vvv
                    table.ForeignKey(
                        name: "FK_PersonExtensions_Person_PersonId",
                        column: x => x.PersonId,
                        principalTable: "Person",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                }
// ^^^ UNTIL HERE ^^^
);
...
            migrationBuilder.CreateIndex(
                name: "IX_PersonExtensions_PersonId",
                table: "PersonExtensions",
                column: "PersonId");

如何防止迁移构建器Persons在扩展项目的迁移中添加表,但仍将外键添加到与另一个项目一起创建的已经存在的表中?我希望能够从 fluent api 执行此操作,而无需手动修改生成的迁移,因为这容易出错。请注意,该项目有数百个实体,并且无法手动修改生成的迁移。

我一直在尝试但不起作用:

我在 OnModelCreating 中添加了外键,如下所示:

    modelBuilder.Entity("PersonExtension").HasOne("Person").WithOne();

如果我只这样做,它会添加“Persons”表和来自基本模型 DLL 的所有链接实体(为简单起见,此处未显示)。

我使用modelBuilder.Ignore()删除了基本 DLL 中定义的所有实体,但现在它添加了"Persons"表,但没有基本模型中的其余嵌套实体(仅存在原始字段)。

我再次明确添加modelBuilder.Model.RemoveEntityType("Person");modelBuilder.Ignore("Person");它仍然创建Persons表,我猜是因为它看到添加了外键......

任何帮助将不胜感激。谢谢!

4

0 回答 0