- Одна сущность имеет множество версий EntityVersion - EntityVersion.EntityId
- Одна сущность имеет одну (необязательно) EntityVersion - Entity.LatestEntityVersionId
- Один набор изменений содержит много EntityVersion — EntityVersion.ChangesetId (модель набора изменений опущена для краткости — я включил эту деталь только из-за составного индекса в построителе моделей)
Код: Выделить всё
public class Entity
{
public Guid Id { get; set; }
public Guid? LatestEntityVersionId { get; set; }
}
public class EntityVersion
{
public Guid Id { get; set; }
public Guid EntityId { get; set; }
public Guid ChangesetId { get; set; }
public string? InternalName { get; set; }
public string? MigrationSource { get; set; }
// More unrelated properties
}
Код: Выделить всё
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(b =>
{
b.HasOne()
.WithMany()
.HasForeignKey(x => x.LatestEntityVersionId);
b.ToTable("Entities");
});
modelBuilder.Entity(b =>
{
b.HasOne()
.WithMany()
.HasForeignKey(x => x.EntityId)
.OnDelete(DeleteBehavior.Restrict);
b.HasOne()
.WithMany()
.HasForeignKey(x => x.ChangeSetId);
b.Property(x => x.InternalName).HasColumnName("InternalName");
b.Property(x => x.MigrationSource).HasColumnName("MigrationSource");
b.HasIndex(x => x.ChangeSetId);
b.HasIndex(x => x.EntityId);
b.HasIndex(x => new { x.ChangeSetId, x.EntityId })
.IsUnique();
b.ToTable("EntityVersions");
});
}
Код: Выделить всё
public class EntityVersion
{
// ...
public virtual Entity Entity { get; set; } = null!;
// ...
}
Код: Выделить всё
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(b =>
{
//...
b.HasOne(x => x.Entity)
.WithMany()
.HasForeignKey(x => x.EntityId)
.OnDelete(DeleteBehavior.Restrict);
b.Navigation(x => x.Entity).AutoInclude();
//...
}
}
Однако, когда я опубликовал PR, создатель истории попросил меня удалить свойство EntityVersion.EntityId в пользу теневого свойства, основанного на соглашении. Нет проблем, подумал я, просто удалите свойство и укажите все ссылки наentityVersion.Entity.Id.
Однако на самом деле произошло то, что при миграции были удалены существующие внешние ключи и индексы EntityId (но остался сам столбец), добавлен новый столбец с именем EntityVersion_EntityId и добавлен внешний ключ и индексы обратно для этого нового столбца.
Вот созданный миграция:
Код: Выделить всё
public partial class EntityRelationshipsFixed : Migration
{
///
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EntityVersions_Entities_EntityId",
table: "EntityVersions");
migrationBuilder.DropIndex(
name: "IX_EntityVersions_ChangeSetId_EntityId",
table: "EntityVersions");
migrationBuilder.DropIndex(
name: "IX_EntityVersions_EntityId",
table: "EntityVersions");
migrationBuilder.AddColumn(
name: "EntityVersion_EntityId",
table: "EntityVersions",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.CreateIndex(
name: "IX_EntityVersions_ChangeSetId_EntityVersion_EntityId",
table: "EntityVersions",
columns: new[] { "ChangeSetId", "EntityVersion_EntityId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_EntityVersions_EntityVersion_EntityId",
table: "EntityVersions",
column: "EntityVersion_EntityId");
migrationBuilder.AddForeignKey(
name: "FK_EntityVersions_Entities_EntityVersion_EntityId",
table: "EntityVersions",
column: "EntityVersion_EntityId",
principalTable: "Entities",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
///
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EntityVersions_Entities_EntityVersion_EntityId",
table: "EntityVersions");
migrationBuilder.DropIndex(
name: "IX_EntityVersions_ChangeSetId_EntityVersion_EntityId",
table: "EntityVersions");
migrationBuilder.DropIndex(
name: "IX_EntityVersions_EntityVersion_EntityId",
table: "EntityVersions");
migrationBuilder.DropColumn(
name: "EntityVersion_EntityId",
table: "EntityVersions");
migrationBuilder.CreateIndex(
name: "IX_EntityVersions_ChangeSetId_EntityId",
table: "EntityVersions",
columns: new[] { "ChangeSetId", "EntityId" });
migrationBuilder.CreateIndex(
name: "IX_EntityVersions_EntityId",
table: "EntityVersions",
column: "EntityId");
migrationBuilder.AddForeignKey(
name: "FK_EntityVersions_Entities_EntityId",
table: "EntityVersions",
column: "EntityId",
principalTable: "Entities",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
Я пытался явно определить свойство тени в построителе моделей, но это не дает результатов. разница:
Код: Выделить всё
b.HasOne(x => x.Entity)
.WithMany()
.HasForeignKey("EntityId")
.OnDelete(DeleteBehavior.NoAction);
Подробнее здесь: https://stackoverflow.com/questions/798 ... xisting-pr
Мобильная версия