我正在开发一个需要实体可扩展性而无需更改基本实体的项目。我有一个包含基本模型的 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
表,我猜是因为它看到添加了外键......
任何帮助将不胜感激。谢谢!