Use when implementing flexible content schemas using EF Core JSON columns, `OwnsOne().ToJson()` patterns, or designing dynamic field storage that avoids migrations. Covers JSON column configuration, LINQ querying of JSON properties, indexing strategies, and schema evolution patterns for headless CMS architectures.
View on GitHubmelodic-software/claude-code-plugins
content-management-system
plugins/content-management-system/skills/dynamic-schema-design/SKILL.md
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/melodic-software/claude-code-plugins/blob/main/plugins/content-management-system/skills/dynamic-schema-design/SKILL.md -a claude-code --skill dynamic-schema-designInstallation paths:
.claude/skills/dynamic-schema-design/# Dynamic Schema Design with EF Core JSON Columns
Guidance for implementing flexible content schemas using EF Core JSON columns, enabling dynamic custom fields without database migrations.
## When to Use This Skill
- Designing custom field storage for CMS content types
- Implementing dynamic properties that vary per content instance
- Avoiding frequent database migrations for schema changes
- Querying JSON data with LINQ in EF Core
- Planning indexing strategies for JSON columns
- Migrating from EAV (Entity-Attribute-Value) to JSON storage
## EF Core JSON Column Fundamentals
### Basic Configuration (.NET 10 / EF Core 10)
```csharp
// Entity with JSON-stored custom fields
public class ContentItem
{
public Guid Id { get; set; }
public string ContentType { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime CreatedUtc { get; set; }
// JSON column for dynamic fields
public CustomFieldsData CustomFields { get; set; } = new();
}
// Owned entity stored as JSON
public class CustomFieldsData
{
public Dictionary<string, object?> Fields { get; set; } = new();
public Dictionary<string, FieldMetadata> Metadata { get; set; } = new();
}
public class FieldMetadata
{
public string FieldType { get; set; } = string.Empty;
public bool IsRequired { get; set; }
public string? DisplayName { get; set; }
}
```
### DbContext Configuration
```csharp
public class ContentDbContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ContentItem>(entity =>
{
entity.HasKey(e => e.Id);
// Configure JSON column with ToJson()
entity.OwnsOne(e => e.CustomFields, builder =>
{
builder.ToJson();
});
});
}
}
```
## JSON Column Patterns
### Pattern 1: Typed Custom Fields
Best for when field schemas are known at compile time.
```csharp
// Strongly