スキル一覧に戻る
ademceper

auto-migration

by ademceper

1🍴 0📅 2026年1月23日
GitHubで見るManusで実行

SKILL.md


name: auto-migration description: Automatically detect schema changes and manage EF Core migrations trigger: "entity change OR dbcontext change OR create migration" allowed-tools:

  • Bash(dotnet ef)
  • Bash(dotnet build)
  • Bash(git diff)
  • Read
  • Write
  • Edit
  • Glob
  • Grep

Auto Migration Manager

Automatically detects database schema changes and manages Entity Framework Core migrations.

Trigger Conditions

  • Entity class modified (properties added/removed/changed)
  • Entity configuration modified (IEntityTypeConfiguration)
  • DbContext modified (DbSet added/removed)
  • Value object changed
  • Index or constraint added

Detection Strategy

1. Monitor Entity Changes

# Track changes in entity files
git diff --name-only HEAD | grep -E "Domain/.*/(Entities|ValueObjects)/.*\.cs$"

# Check for property changes
git diff HEAD -- "*.cs" | grep -E "^\+.*public.*\{ get;|^\-.*public.*\{ get;"

2. Schema Change Types

Change TypeExampleMigration Impact
Add Propertypublic string Sku { get; }Add column
Remove PropertyDelete propertyDrop column (⚠️ Data loss)
Rename PropertyName → TitleRename column
Change TypeintlongAlter column
Add RelationshipNavigation propertyAdd foreign key
Add Index[Index] attributeCreate index
Change LengthMaxLength(50)MaxLength(100)Alter column

3. Detect Pending Changes

# Check if model has changes vs database
dotnet ef migrations has-pending-model-changes \
  --project Merge.Infrastructure \
  --startup-project Merge.API

# List pending migrations
dotnet ef migrations list \
  --project Merge.Infrastructure \
  --startup-project Merge.API

Migration Generation

Naming Convention

{Timestamp}_{Action}{Entity}{Detail}

Examples:
- 20240115_AddSkuToProduct
- 20240115_CreateReviewsTable
- 20240115_AddIndexOnOrderUserId
- 20240115_RemoveDeprecatedFields
- 20240115_RenameProductTitleToName

Generate Migration

# Standard migration
dotnet ef migrations add AddSkuToProduct \
  --project Merge.Infrastructure \
  --startup-project Merge.API \
  --output-dir Data/Migrations

# With specific context (if multiple)
dotnet ef migrations add AddSkuToProduct \
  --context CatalogDbContext \
  --project Merge.Infrastructure \
  --startup-project Merge.API

Review Before Apply

ALWAYS review the generated migration:

// Check Up() method
protected override void Up(MigrationBuilder migrationBuilder)
{
    // ✅ Safe: Add column with default
    migrationBuilder.AddColumn<string>(
        name: "Sku",
        table: "Products",
        type: "character varying(50)",
        maxLength: 50,
        nullable: true);  // Start nullable for existing data

    // ⚠️ Dangerous: Drop column
    migrationBuilder.DropColumn(
        name: "OldField",
        table: "Products");

    // ⚠️ Very Dangerous: Drop table
    migrationBuilder.DropTable(name: "OldProducts");
}

// Check Down() method for reversibility
protected override void Down(MigrationBuilder migrationBuilder)
{
    // Should reverse Up() operations
}

Safe Migration Patterns

1. Add Non-Nullable Column

// Step 1: Add as nullable
migrationBuilder.AddColumn<string>(
    name: "Sku",
    table: "Products",
    nullable: true);

// Step 2: Populate data
migrationBuilder.Sql(
    "UPDATE \"Products\" SET \"Sku\" = 'SKU-' || \"Id\"::text WHERE \"Sku\" IS NULL");

// Step 3: Make non-nullable
migrationBuilder.AlterColumn<string>(
    name: "Sku",
    table: "Products",
    nullable: false);

2. Rename Column (Zero Downtime)

// Step 1: Add new column
migrationBuilder.AddColumn<string>(
    name: "Title",
    table: "Products",
    nullable: true);

// Step 2: Copy data
migrationBuilder.Sql(
    "UPDATE \"Products\" SET \"Title\" = \"Name\"");

// Step 3: (Deploy code that reads both)

// Step 4: Drop old column (separate migration)
migrationBuilder.DropColumn(name: "Name", table: "Products");

3. Change Column Type

// PostgreSQL specific - may need data conversion
migrationBuilder.Sql(@"
    ALTER TABLE ""Products""
    ALTER COLUMN ""Price"" TYPE numeric(18,4)
    USING ""Price""::numeric(18,4)");

4. Add Index Concurrently (PostgreSQL)

// For large tables - don't lock
migrationBuilder.Sql(@"
    CREATE INDEX CONCURRENTLY ""IX_Orders_UserId""
    ON ""Orders"" (""UserId"")");

// Note: CONCURRENTLY cannot be in transaction
// Set in migration:
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
    // Mark as non-transactional
}

Dangerous Operations Alert

🚨 HIGH RISK Operations

// Data Loss Risk
migrationBuilder.DropTable("Products");     // All data lost
migrationBuilder.DropColumn("Price", ...);  // Column data lost

// Lock Table (Large tables)
migrationBuilder.AddColumn<string>(         // Table locked during ADD
    name: "NewColumn",
    nullable: false,                        // Requires default or rewrite
    defaultValue: "");

// Index Creation (Large tables)
migrationBuilder.CreateIndex(               // Table locked during CREATE
    name: "IX_Orders_UserId",
    table: "Orders",
    column: "UserId");

Safe Alternatives

// Instead of DROP COLUMN immediately
// 1. Stop writing to column
// 2. Deploy code ignoring column
// 3. Drop in future migration

// Instead of ADD non-nullable column
// Add as nullable → populate → alter to non-nullable

// Instead of CREATE INDEX
// Use CONCURRENTLY (PostgreSQL)

Apply Migrations

Development

# Apply all pending migrations
dotnet ef database update \
  --project Merge.Infrastructure \
  --startup-project Merge.API

# Apply specific migration
dotnet ef database update AddSkuToProduct \
  --project Merge.Infrastructure \
  --startup-project Merge.API

# Rollback to specific migration
dotnet ef database update PreviousMigrationName \
  --project Merge.Infrastructure \
  --startup-project Merge.API

Production (Script-based)

# Generate SQL script
dotnet ef migrations script \
  --project Merge.Infrastructure \
  --startup-project Merge.API \
  --idempotent \
  --output migration.sql

# Review script before applying
cat migration.sql

# Apply via psql or database tool
psql -h localhost -U postgres -d merge -f migration.sql

Idempotent Scripts

# Always use --idempotent for production
dotnet ef migrations script \
  --idempotent \
  --output migration.sql

# This generates:
IF NOT EXISTS(SELECT * FROM "__EFMigrationsHistory" WHERE "MigrationId" = '...')
BEGIN
    -- Migration code
END;

Rollback Strategy

Rollback Last Migration

# Remove last migration (if not applied)
dotnet ef migrations remove \
  --project Merge.Infrastructure \
  --startup-project Merge.API

# Revert applied migration
dotnet ef database update PreviousMigrationName \
  --project Merge.Infrastructure \
  --startup-project Merge.API

Emergency Rollback

-- Manual rollback (PostgreSQL)
-- 1. Run Down() SQL manually
-- 2. Remove from history
DELETE FROM "__EFMigrationsHistory"
WHERE "MigrationId" = '20240115123456_AddSkuToProduct';

Execution Flow

1. Entity/Configuration Change Detected
   ↓
2. Check for Pending Model Changes
   ↓
3. Generate Migration with Proper Name
   ↓
4. Review Generated Code
   ↓
5. Check for Dangerous Operations
   ↓
6. If Safe → Apply to Dev Database
   ↓
7. Run Tests
   ↓
8. Generate Idempotent Script for Prod
   ↓
9. Report Migration Status

Output Format

## Migration Analysis

**Changed Files:**
- Merge.Domain/Entities/Product.cs (+2 lines)

**Detected Changes:**
1. Added property: `public string Sku { get; private set; }`

**Generated Migration:** `20240115_AddSkuToProduct`

**Operations:**
| Operation | Risk | Impact |
|-----------|------|--------|
| ADD COLUMN Sku | Low | No data loss |

**Commands:**
```bash
# Preview
dotnet ef migrations script --idempotent

# Apply (Dev)
dotnet ef database update

# Apply (Prod)
psql -f migration.sql

Warnings: None


## Validation Checks

**Before Generation:**
- [ ] Entity configuration exists
- [ ] Property has proper type mapping
- [ ] Relationships properly defined
- [ ] No circular dependencies

**Before Apply:**
- [ ] Migration reviewed
- [ ] No DROP operations (or intentional)
- [ ] No large table locks
- [ ] Down() method works
- [ ] Tests pass

**After Apply:**
- [ ] Database accessible
- [ ] Application starts
- [ ] Queries work
- [ ] No performance regression

スコア

総合スコア

40/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です