Configurations
表具有主键 Id
和引用 CurrentVersionId
表中的 Id
列的外键 ConfigurationVersions
。 ConfigurationVersions
表具有主键 Id
和引用 ConfigurationId
表中的 Id
列的外键 Configurations
。
基本上,主要任务是如果表相互引用,如何播种数据。
我有两种例外情况。第一个涉及到
FK_Configurations_ConfigurationVersions_CurrentVersionId
如果我在 _context.SaveChanges
之后调用 DeviceConfiguration
,另一个是在创建版本之后添加之后的 FK_Configurations_ConfigurationVersions_configurationId
异常数据:
严重性:错误
sql状态:23503
MessageText:表“ConfigurationVersions”的插入或更新违反了外键约束“FK_ConfigurationVersions_Configurations_ConfigurationId”
详细信息:详细信息已被编辑,因为它可能包含敏感数据。在连接字符串中指定“包含错误详细信息”以包含此信息。
模式名称:public
表名称:配置版本
约束名称:FK_ConfigurationVersions_Configurations_ConfigurationId*
代码:
[Table("Configurations")]
public class DeviceConfiguration
{
public int Id { get; set; }
public int CurrentVersionId { get; set; }
}
[Table("ConfigurationVersions")]
public class DeviceConfigurationVersion
{
public int Id { get; set; }
public int ConfigurationId { get; set; }
}
这是我创建这些表的迁移
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:device_configuration_source", "Versioned,Duplicated,RollBacked,Imported")
.Annotation("Npgsql:Enum:device_configuration_state", "Published,Draft,Unsaved")
.Annotation("Npgsql:Enum:device_configuration_type", "Factory,Custom");
migrationBuilder.CreateTable(
name: "Configurations",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CurrentVersionId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Configurations", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ConfigurationVersions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ConfigurationId = table.Column<int>(type: "integer", nullable: false),
},
constraints: table =>
{
table.PrimaryKey("PK_ConfigurationVersions", x => x.Id);
table.ForeignKey(
name: "FK_ConfigurationVersions_Configurations_ConfigurationId",
column: x => x.ConfigurationId,
principalTable: "Configurations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.AddForeignKey(
name: "FK_Configurations_ConfigurationVersions_CurrentVersionId",
table: "Configurations",
column: "CurrentVersionId",
principalTable: "ConfigurationVersions",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(name: "ConfigurationVersions");
migrationBuilder.DropTable(name: "Configurations");
}
数据播种器
public class DataSeeder
{
private readonly ApplicationDbContext _context;
public DataSeeder(ApplicationDbContext context)
{
_context = context;
}
public void SeedData()
{
if (_context.Configurations != null && _context.Configurations.Any())
{
return;
}
for (int i = 1; i <= 100; i++)
{
DeviceConfiguration configuration = new()
{
CurrentVersionId = i
};
_context.Configurations?.Add(configuration);
DeviceConfigurationVersion version = new()
{
ConfigurationId = configuration.Id
};
_context.ConfigurationVersions?.Add(version);
_context.SaveChanges();
configuration.CurrentVersionId = version.Id;
_context.SaveChanges();
}
}
}
您没有设置
Id
的显式值,因此 configuration.Id
等于 0
DeviceConfiguration configuration = new()
{
CurrentVersionId = i
};
在这里,您只需将
0
分配给 version.configuration.Id
DeviceConfigurationVersion version = new()
{
ConfigurationId = configuration.Id
};
仅在此行之后,查询才会发送到 SQL,该 SQL 创建一行并生成
Id
的实际值。
_context.SaveChanges();
所以你有两个选择
DeviceConfiguration configuration = new()
{
CurrentVersionId = i
};
_context.SaveChanges();
DeviceConfigurationVersion version = new()
{
ConfigurationId = configuration.Id
};
_context.SaveChanges();
Id
,并操作对象即可。[Table("Configurations")]
public class DeviceConfiguration
{
public int Id { get; set; }
public DeviceConfigurationVersion CurrentVersion { get; set; }
}
[Table("ConfigurationVersions")]
public class DeviceConfigurationVersion
{
public int Id { get; set; }
public DeviceConfiguration Configuration { get; set; }
}