feat(config): forward-only migration deleting orphaned SystemPlatform namespace data (clean break)
This commit is contained in:
+1758
File diff suppressed because it is too large
Load Diff
+120
@@ -0,0 +1,120 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Configuration.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Forward-only DATA-cleanup migration for the Galaxy clean break: the
|
||||
/// <c>NamespaceKind.SystemPlatform</c> enum member was removed (Galaxy is now an
|
||||
/// Equipment-kind driver). <c>Namespace.Kind</c> is persisted as a string via
|
||||
/// <c>HasConversion<string></c>, so any leftover row with <c>Kind = 'SystemPlatform'</c>
|
||||
/// would throw at materialisation time (no matching enum member) the moment the new code
|
||||
/// reads the table. This deletes those namespaces plus everything that hung off them.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// There is NO schema/model change in this migration — the model snapshot is unchanged.
|
||||
/// The unique index <c>UX_Namespace_Cluster_Kind</c> (unique on <c>ClusterId, Kind</c>) is
|
||||
/// intentionally KEPT: <c>Simulated</c> remains a reserved kind, so one-of-each-kind-per-cluster
|
||||
/// is still the correct constraint.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The cross-table relationships in this graph are LOGICAL foreign keys (string Id columns,
|
||||
/// e.g. <c>DriverInstance.NamespaceId</c> → <c>Namespace.NamespaceId</c>,
|
||||
/// <c>Tag.DriverInstanceId</c> → <c>DriverInstance.DriverInstanceId</c>) enforced by
|
||||
/// <c>sp_ValidateDraft</c>, NOT physical DB FK constraints — only the <c>*.ClusterId</c>
|
||||
/// relationships are real DB FKs. So no FK constraint can be violated here. The deletes are
|
||||
/// nonetheless ordered child→parent so no orphaned rows are left behind, and every statement
|
||||
/// is keyed off the set of SystemPlatform namespaces, so on a DB with zero such rows every
|
||||
/// DELETE simply affects 0 rows (idempotent / safe to run repeatedly).
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public partial class CleanupSystemPlatformNamespaces : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Delete in child -> parent order. Everything is keyed off the set of namespaces whose
|
||||
// Kind = 'SystemPlatform' (the string form persisted by HasConversion<string>), funnelled
|
||||
// through the DriverInstances that lived in those namespaces.
|
||||
migrationBuilder.Sql(@"
|
||||
-- Defensive: SystemPlatform namespaces historically held only EquipmentId-NULL mirror tags, but a
|
||||
-- stray equipment-scoped tag / Equipment could be bound to a SystemPlatform-namespace driver. Clean
|
||||
-- both, plus anything that FKs into the affected Equipment (VirtualTag / ScriptedAlarm / state).
|
||||
|
||||
-- Grandchildren of the affected Equipment ------------------------------------------------
|
||||
-- ScriptedAlarmState is keyed by ScriptedAlarm.ScriptedAlarmId; remove before its ScriptedAlarm.
|
||||
DELETE FROM [ScriptedAlarmState]
|
||||
WHERE [ScriptedAlarmId] IN (
|
||||
SELECT [ScriptedAlarmId] FROM [ScriptedAlarm]
|
||||
WHERE [EquipmentId] IN (
|
||||
SELECT [EquipmentId] FROM [Equipment]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'))));
|
||||
|
||||
DELETE FROM [ScriptedAlarm]
|
||||
WHERE [EquipmentId] IN (
|
||||
SELECT [EquipmentId] FROM [Equipment]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')));
|
||||
|
||||
DELETE FROM [VirtualTag]
|
||||
WHERE [EquipmentId] IN (
|
||||
SELECT [EquipmentId] FROM [Equipment]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform')));
|
||||
|
||||
-- Children of the affected DriverInstances ------------------------------------------------
|
||||
-- Tags bound to those drivers: both EquipmentId-NULL mirror tags AND any equipment-scoped tag.
|
||||
DELETE FROM [Tag]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'));
|
||||
|
||||
DELETE FROM [PollGroup]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'));
|
||||
|
||||
DELETE FROM [Device]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'));
|
||||
|
||||
DELETE FROM [Equipment]
|
||||
WHERE [DriverInstanceId] IN (
|
||||
SELECT [DriverInstanceId] FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform'));
|
||||
|
||||
-- The DriverInstances themselves ----------------------------------------------------------
|
||||
DELETE FROM [DriverInstance]
|
||||
WHERE [NamespaceId] IN (
|
||||
SELECT [NamespaceId] FROM [Namespace] WHERE [Kind] = 'SystemPlatform');
|
||||
|
||||
-- The SystemPlatform namespaces (the rows that would crash EF on read) --------------------
|
||||
DELETE FROM [Namespace] WHERE [Kind] = 'SystemPlatform';
|
||||
");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Forward-only data cleanup: the deleted SystemPlatform namespaces and their dependent
|
||||
// rows cannot be reconstructed (the data is gone, and SystemPlatform is no longer a valid
|
||||
// NamespaceKind). Intentionally a no-op rather than a throw, so rolling back a LATER
|
||||
// migration does not blow up on this one.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user