xiaohongshu
xiaohongshu
dotnet-efcore-guidelines
Entity Framework Core best practices for Clean Architecture projects. Covers DbContext, entity configurations, repository pattern, migrations, and PostgreSQL-specific features.
Full skill instructions
Project-Agnostic EF Core Patterns
Placeholders use
{Placeholder}syntax - see docs/TEMPLATE_GLOSSARY.md.
This skill provides comprehensive best practices for using Entity Framework Core with PostgreSQL in Clean Architecture projects. It details conventions for DbContext, entity configurations, repository patterns, migrations, and PostgreSQL-specific features.
Triggered by:
**/Persistence/**/*.cs, **/Repositories/**/*.cs, **/*DbContext.cs, **/Configurations/**/*.csThe persistence layer ({Project}.Persistence) is responsible for data access and storage. It implements interfaces defined in the Application layer, adhering to Clean Architecture principles.
graph TD
subgraph Application Layer
A[I{Entity}Repository] --> B[{Entity}]
B[{Entity}] --> C[Domain Layer]
end
subgraph Persistence Layer
D[{DbContext}] --> B
E[{Entity}Repository] --> D
E --> A
end
A -- Implemented by --> E
C -- Used by --> B
D -- Configures --> B
For more detailed examples, refer to the resources/ folder within this skill.
| Resource | Description |
|---|---|
| dbcontext-patterns.md | DbContext configuration, SaveChangesAsync override |
| entity-configuration.md | IEntityTypeConfiguration, TPT, PostgreSQL functions |
| repository-pattern.md | GenericRepository, custom repositories |
| querying-patterns.md | Include, Select, projections, performance |
| migrations.md | Creating and applying migrations |
The {DbContext} manages database interactions.
// File: {Project}.Persistence/{DbContext}.cs
public class {DbContext} : DbContext
{
public {DbContext}(DbContextOptions<{DbContext}> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Automatically applies all IEntityTypeConfiguration<T> from the assembly
modelBuilder.ApplyConfigurationsFromAssembly(typeof({DbContext}).Assembly);
}
// Override SaveChangesAsync for cross-cutting concerns like auditing or soft deletes
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
// Example: Audit logging or automatic timestamp updates
foreach (var entry in ChangeTracker.Entries())
{
// Handle CreatedAt, UpdatedAt logic
}
return base.SaveChangesAsync(cancellationToken);
}
public DbSet<{Entity}> {Entities} { get; set; } = null!;
public DbSet<{ParentEntity}> {ParentEntities} { get; set; } = null!;
// ... other DbSets
}
For more details, see dbcontext-patterns.md.
All entity-specific configurations are done using IEntityTypeConfiguration<T> in separate classes.
// File: {Project}.Persistence/Configurations/Entities/{Entity}Configuration.cs
public class {Entity}Configuration : IEntityTypeConfiguration<{Entity}>
{
public void Configure(EntityTypeBuilder<{Entity}> builder)
{
// Project Standard: Table Per Type (TPT) inheritance strategy
builder.UseTptMappingStrategy();
// Project Standard: UUIDv7 primary keys for main entities
builder.Property(e => e.Id).HasDefaultValueSql("uuidv7()");
// Database-level defaults are acceptable here, not in domain entities
builder.Property(e => e.ViewCount).HasDefaultValue(0);
builder.Property(e => e.Title).HasMaxLength(200).IsRequired();
builder.Property(e => e.Description).HasMaxLength(5000);
// Example relationship configuration
builder.HasOne(e => e.{ParentEntity})
.WithMany()
.HasForeignKey(e => e.{ParentEntity}Id)
.OnDelete(DeleteBehavior.Restrict);
}
}
For more details, see entity-configuration.md.
Repositories abstract data access. Interfaces reside in the Application layer, and implementations are in the Persistence layer.
CRITICAL RULE: Repositories MUST return DOMAIN ENTITIES, not DTOs. DTO mapping always happens in the Application layer handlers via AutoMapper.
// File: {Project}.Application/Contracts/Persistence/I{Entity}Repository.cs (Application Layer)
public interface I{Entity}Repository : IGenericRepository<{Entity}, {IdType}>
{
Task<List<{Entity}>> Get{Entities}WithDetails(); // Returns List<{Entity}>
Task<{Entity}?> Get{Entity}WithDetails({IdType} id); // Returns {Entity}?
}
// File: {Project}.Persistence/Repositories/{Entity}Repository.cs (Persistence Layer)
public class {Entity}Repository : GenericRepository<{Entity}, {IdType}>, I{Entity}Repository
{
private readonly {DbContext} _dbContext;
public {Entity}Repository({DbContext} dbContext) : base(dbContext) => _dbContext = dbContext;
public async Task<List<{Entity}>> Get{Entities}WithDetails()
{
return await _dbContext.{Entities}
.Include(e => e.{LookupEntity})
.Include(e => e.{RelatedEntity1})
.Include(e => e.{RelatedEntity2})
.ToListAsync(); // Returns entities
}
}
For more details, see repository-pattern.md.
Efficient querying is crucial for performance. Avoid N+1 issues by using eager loading (Include) and projections (Select).
// Example: Query with eager loading and projection to DTO (in Application Layer Handler)
public async Task<List<{Entity}ListDto>> Handle(Get{Entity}ListRequest request, CancellationToken cancellationToken)
{
var {entities} = await _{entity}Repository.Get{Entities}WithDetails(); // Repository returns entities
return _mapper.Map<List<{Entity}ListDto>>({entities}); // Handler maps to DTOs
}
// Example: Using AsNoTracking for read-only queries (in Repository)
public async Task<List<{Entity}>> Get{Entities}ReadOnly()
{
return await _dbContext.{Entities}
.AsNoTracking() // Disables change tracking for performance
.Include(e => e.{ParentEntity})
.ToListAsync();
}
For more details, see querying-patterns.md.
Database schema changes are managed through EF Core migrations.
# Create a new migration for schema changes
dotnet ef migrations add AddNewFieldTo{Entity} --project {Project}.Persistence
# Apply pending migrations to the database
dotnet ef database update --project {Project}.Persistence
# Generate SQL script for production deployment
dotnet ef migrations script --idempotent --output migrations/release.sql --project {Project}.Persistence
For more details, see migrations.md.
Guid (or {IdType}), except for lookup tables which use int (or {LookupIdType}).int instead of long unless explicitly required for large values (e.g., file sizes, pagination cursors).public int ViewCount { get; set; } = 0;). Set defaults in application handlers or use database-level defaults via IEntityTypeConfiguration.UUIDv7 for primary keys and PostGIS for spatial data handling.Related Documentation:
docs/DOMAIN.md - Conceptual domain model.docs/ARCHITECTURE.md - Overall system architecture.clean-architecture-rules - Dependency enforcement.xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience