Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.ConfigurationDatabase/Migrations/20261022133907_ReviewRemediationIndexes.cs
T
Joseph Doherty 1627513fdb feat(configdb): ReviewRemediationIndexes migration — AuditLog (Kind, Actor) + AuditLogEntries composite indexes
AuditLog indexes are raw SQL ON ps_AuditLog_Month so they stay partition-aligned for the switch purge.
2026-10-22 09:42:02 -04:00

73 lines
3.0 KiB
C#

using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
{
/// <summary>Review-remediation composite indexes on AuditLog (partition-aligned, raw SQL) and AuditLogEntries.</summary>
public partial class ReviewRemediationIndexes : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateIndex(
name: "IX_AuditLogEntries_EntityType_Timestamp",
table: "AuditLogEntries",
columns: new[] { "EntityType", "Timestamp" },
descending: new[] { false, true });
migrationBuilder.CreateIndex(
name: "IX_AuditLogEntries_Timestamp_Id",
table: "AuditLogEntries",
columns: new[] { "Timestamp", "Id" },
descending: new bool[0]);
migrationBuilder.CreateIndex(
name: "IX_AuditLogEntries_User_Timestamp",
table: "AuditLogEntries",
columns: new[] { "User", "Timestamp" },
descending: new[] { false, true });
// AuditLog is monthly-partitioned (ps_AuditLog_Month) with a partition-switch
// purge, so these two indexes MUST be partition-aligned. EF's CreateIndex cannot
// express the ON ps_AuditLog_Month(OccurredAtUtc) clause -> raw SQL, exactly as
// IX_AuditLog_Node_Occurred (AddAuditLogSourceNode). Kind is a PERSISTED computed
// column, so it is indexable. On a large production AuditLog consider adding
// WITH (ONLINE = ON) (Enterprise edition) to the generated script.
migrationBuilder.Sql(@"
CREATE NONCLUSTERED INDEX IX_AuditLog_Kind_Occurred
ON dbo.AuditLog (Kind, OccurredAtUtc DESC)
ON ps_AuditLog_Month(OccurredAtUtc);");
migrationBuilder.Sql(@"
CREATE NONCLUSTERED INDEX IX_AuditLog_Actor_Occurred
ON dbo.AuditLog (Actor, OccurredAtUtc DESC)
ON ps_AuditLog_Month(OccurredAtUtc);");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AuditLogEntries_EntityType_Timestamp",
table: "AuditLogEntries");
migrationBuilder.DropIndex(
name: "IX_AuditLogEntries_Timestamp_Id",
table: "AuditLogEntries");
migrationBuilder.DropIndex(
name: "IX_AuditLogEntries_User_Timestamp",
table: "AuditLogEntries");
migrationBuilder.Sql(@"
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Actor_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
DROP INDEX IX_AuditLog_Actor_Occurred ON dbo.AuditLog;");
migrationBuilder.Sql(@"
IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_AuditLog_Kind_Occurred' AND object_id = OBJECT_ID('dbo.AuditLog'))
DROP INDEX IX_AuditLog_Kind_Occurred ON dbo.AuditLog;");
}
}
}