Agent Skill
2/7/2026ef-core-configuration
Use this skill when configuring Entity Framework Core entities using the Fluent API.
M
michaellperry
1GitHub Stars
1Views
npx skills add michaellperry/aaad
SKILL.md
| Name | ef-core-configuration |
| Description | Use this skill when configuring Entity Framework Core entities using the Fluent API. |
name: ef-core-configuration description: Use this skill when configuring Entity Framework Core entities using the Fluent API.
EF Core Configuration Class Patterns
For each entity, create a corresponding configuration class following these exact patterns.
Configuration Class Structure
using GloboTicket.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace GloboTicket.Infrastructure.Data.Configurations;
/// <summary>
/// Entity Framework Core configuration for the {EntityName} entity.
/// Defines table structure, constraints, indexes, and relationships.
/// </summary>
public class {EntityName}Configuration : IEntityTypeConfiguration<{EntityName}>
{
/// <summary>
/// Configures the {EntityName} entity.
/// </summary>
/// <param name="builder">The entity type builder.</param>
public void Configure(EntityTypeBuilder<{EntityName}> builder)
{
// Configuration in exact order...
}
}
Configuration Order (Critical!)
Follow this EXACT order:
1. Table Name
builder.ToTable("Shows"); // Plural, PascalCase
2. Primary Key
builder.HasKey(s => s.Id);
builder.Property(s => s.Id).ValueGeneratedOnAdd();
3. Composite Alternate Key (MultiTenantEntity ONLY)
builder.HasAlternateKey(e => new { e.TenantId, e.EntityGuid });
4. Indexes
builder.HasIndex(e => e.EntityGuid); // For MultiTenantEntity
5. Property Configurations
builder.Property(s => s.StartTime).IsRequired();
builder.Property(s => s.Name).IsRequired().HasMaxLength(100);
6. Foreign Key Relationships
builder.HasOne(s => s.Venue)
.WithMany(v => v.Shows) // Always specify the collection on the parent
.HasForeignKey(s => s.VenueId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
7. Inherited Property Configurations
builder.Property(s => s.CreatedAt).IsRequired();
builder.Property(s => s.UpdatedAt).IsRequired(false);
Child Entity Configuration Example
For entities inheriting from Entity (like Show):
public class ShowConfiguration : IEntityTypeConfiguration<Show>
{
public void Configure(EntityTypeBuilder<Show> builder)
{
// 1. Table name
builder.ToTable("Shows");
// 2. Primary key
builder.HasKey(s => s.Id);
builder.Property(s => s.Id).ValueGeneratedOnAdd();
// 3. Property configurations
builder.Property(s => s.StartTime).IsRequired();
// 4. Foreign key relationships
builder.HasOne(s => s.Venue)
.WithMany(v => v.Shows) // Collection on Venue
.HasForeignKey(s => s.VenueId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
builder.HasOne(s => s.Act)
.WithMany(a => a.Shows) // Collection on Act
.HasForeignKey(s => s.ActId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
// 5. Inherited property configurations
builder.Property(s => s.CreatedAt).IsRequired();
builder.Property(s => s.UpdatedAt).IsRequired(false);
}
}
MultiTenantEntity Configuration Example
For entities inheriting from MultiTenantEntity:
public class ActConfiguration : IEntityTypeConfiguration<Act>
{
public void Configure(EntityTypeBuilder<Act> builder)
{
// 1. Table name
builder.ToTable("Acts");
// 2. Primary key
builder.HasKey(a => a.Id);
builder.Property(a => a.Id).ValueGeneratedOnAdd();
// 3. Composite alternate key for multi-tenant uniqueness
builder.HasAlternateKey(a => new { a.TenantId, a.ActGuid });
// 4. Index on ActGuid for queries
builder.HasIndex(a => a.ActGuid);
// 5. Property configurations
builder.Property(a => a.ActGuid).IsRequired();
builder.Property(a => a.Name).IsRequired().HasMaxLength(100);
// 6. Foreign key relationship to Tenant with cascade delete
builder.HasOne(a => a.Tenant)
.WithMany()
.HasForeignKey(a => a.TenantId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
// 7. Inherited property configurations
builder.Property(a => a.CreatedAt).IsRequired();
builder.Property(a => a.UpdatedAt).IsRequired(false);
}
}
Relationship Configuration Pattern
CRITICAL: When creating a child entity with a relationship to a parent entity, you MUST:
-
Add the collection navigation property to the parent entity
- Example: When creating
Showthat belongs toVenue, addpublic ICollection<Show> Shows { get; set; } = new List<Show>();toVenue - Use XML documentation:
/// <summary>The collection of Shows held at this venue.</summary>
- Example: When creating
-
Configure the relationship on the many (child) side using HasOne().WithMany(parent => parent.Collection).HasForeignKey()
- Example in
ShowConfiguration:
builder.HasOne(s => s.Venue) .WithMany(v => v.Shows) // Reference the collection property you added .HasForeignKey(s => s.VenueId) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - Example in
-
Never use empty
WithMany()- This creates a "shadow" relationship without proper navigation, making the model harder to use and query.
Workflow:
- Read the parent entity file (e.g.,
Venue.cs) - Add the collection navigation property with proper XML documentation
- Write the parent entity file back
- Create the child entity with its navigation property to the parent
- Create the child entity configuration using
WithMany(parent => parent.Collection)
Key Configuration Rules
- Always configure inherited properties (CreatedAt, UpdatedAt)
- Always specify
HasMaxLength()for string properties - Always use
DeleteBehavior.Cascadefor parent-child relationships - Always use descriptive comments for each section
- Always follow the exact order specified above
- Always add collection navigation properties to parent entities when creating new child entities
- Always use
WithMany(parent => parent.Collection)pattern in relationship configuration on the many side - Never skip property configuration - be explicit about all constraints
- Never use data annotations - only Fluent API
- Never use empty
WithMany()- always reference the collection property on the parent
Skills Info
Original Name:ef-core-configurationAuthor:michaellperry
Download