Skip to content

Adding scaffold-generate-aspnet/SKILL.md - #133

Closed
sayedihashimi wants to merge 9 commits into
dotnet:mainfrom
sayedihashimi:sayedha/scaffold-skill
Closed

Adding scaffold-generate-aspnet/SKILL.md#133
sayedihashimi wants to merge 9 commits into
dotnet:mainfrom
sayedihashimi:sayedha/scaffold-skill

Conversation

@sayedihashimi

Copy link
Copy Markdown
Contributor

This should be picked up when a prompt requests to generate content for ASP.NET Core that uses a database. This skill will ensure that best practices are followed when using ASP.NET Core + EF. For example without this skill it's common for copilot to initialize the database in Program.cs instead of using migrations.

This should be picked up when a prompt requests to generate content for ASP.NET Core that uses a database.
This skill will ensure that best practices are followed when using ASP.NET Core + EF. For example without this skill
it's common for copilot to initialize the database in Program.cs instead of using migrations.
Copilot AI review requested due to automatic review settings February 26, 2026 18:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new skill (scaffold-generate-aspnet) that guides Copilot to generate ASP.NET Core code—including Razor Pages, Blazor components, MVC controllers, views, and Minimal API endpoints—without using CLI scaffolding tools. The skill emphasizes best practices such as using EF Core migrations instead of database seeding in Program.cs, matching existing project CSS frameworks and conventions, and properly handling Blazor-specific patterns like [SupplyParameterFromForm] properties.

Changes:

  • Adds comprehensive skill documentation for ASP.NET Core code generation, with detailed workflows covering UI scaffolders (Razor Pages, Blazor, MVC) and API scaffolders (Minimal API, MVC controllers)
  • Provides example scaffolding request formats and step-by-step instructions for discovering project conventions, generating code, setting up Entity Framework, creating test .http files, and verifying the scaffolded code
  • Includes validation checklists and common pitfalls tables to help ensure generated code follows best practices

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/dotnet/skills/scaffold-generate-aspnet/SKILL.md Outdated
Comment thread src/dotnet/skills/scaffold-generate-aspnet/SKILL.md
@jeffschwMSFT

Copy link
Copy Markdown
Member

@sayedihashimi thanks for this skill, please run and past the skill evaluation output in this PR (eng/skill-validator).

sayedihashimi and others added 5 commits February 26, 2026 22:00
Add 4 evaluation scenarios covering:
- Razor Pages CRUD with EF Core and SQLite
- Minimal API endpoints with OpenAPI
- Blazor CRUD components with SupplyParameterFromForm
- Advisory guidance on EF migration best practices

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rewrite prompts in natural human language
- Remove CLI tool restriction rubrics (baseline may use CLI tools)
- Remove package restriction assertions and rubrics
- Remove Blazor-specific assertions (SupplyParameterFromForm, AddInteractiveServerComponents)
- Remove Advisory EF migration scenario
- Keep rubrics focused on quality outcomes the skill should improve

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create .NET 10 projects with model classes for each test scenario:
- razor-pages-crud: Razor Pages webapp with Product/Category models (FK relationship)
- minimal-api: Web API with TodoItem model
- blazor-crud: Blazor Web App with Employee/Department models (FK relationship)

Projects created via dotnet new with vendor libraries (wwwroot/lib) removed.
Eval scenarios updated to use copy_test_files and reference fixture project paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add detailed instructions in Step 4 for enriching Minimal API and MVC API
endpoints with OpenAPI metadata: WithName, WithTags, WithDescription,
Produces, and ProducesValidationProblem. Includes a code example.

Update eval rubric to expect rich OpenAPI metadata on generated endpoints.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sayedihashimi

Copy link
Copy Markdown
Contributor Author

Here is the output of the skill-validator

dotnet run --project .\src\SkillValidator.csproj -p:RunArguments="" -- --runs 1 --results-dir "C:\temp\skills\validator-output\" --tests-dir "C:\data\mycode\skills\src\dotnet\tests\scaffold-generate-aspnet\" "C:\data\mycode\skills\src\dotnet\skills\scaffold-generate-aspnet\"
Using model: claude-opus-4.6, judge-mode: Pairwise
Found 1 skill(s)

⚠  Running with 1 run(s). For statistically significant results, use --runs 5 or higher.
[scaffold-generate-aspnet] � Evaluating...
[scaffold-generate-aspnet] � � scaffold-generate-aspnet: 2,446 tokens (detailed ✓), 16 sections, 6 code blocks
[scaffold-generate-aspnet/Scaffold Razor Pages CRUD with EF Core and SQLite] � Starting scenario
[scaffold-generate-aspnet/Scaffold Razor Pages CRUD with EF Core and SQLite] � Skill activated (skills: scaffold-generate-aspnet; extra tools: skill)
[scaffold-generate-aspnet/Scaffold Razor Pages CRUD with EF Core and SQLite] ✓ All 1 run(s) complete
[scaffold-generate-aspnet/Scaffold Minimal API endpoints with OpenAPI] � Starting scenario
[scaffold-generate-aspnet/Scaffold Minimal API endpoints with OpenAPI] � Skill activated (skills: scaffold-generate-aspnet; extra tools: skill, read_powershell, stop_powershell)
[scaffold-generate-aspnet/Scaffold Minimal API endpoints with OpenAPI] ✓ All 1 run(s) complete
[scaffold-generate-aspnet/Scaffold Blazor CRUD components] � Starting scenario
[scaffold-generate-aspnet/Scaffold Blazor CRUD components] � Skill activated (skills: scaffold-generate-aspnet; extra tools: skill)
[scaffold-generate-aspnet/Scaffold Blazor CRUD components] ✓ All 1 run(s) complete
[scaffold-generate-aspnet] ✅ Done (score: 50.2%)

═══ Skill Validation Results ═══

✓ scaffold-generate-aspnet  +50.2%  [+40.9%, +59.7%] significant  (g=+100.0%)
  Improvement score 50.2% meets threshold of 10.0%

    ↑ Scaffold Razor Pages CRUD with EF Core and SQLite  +40.9%
      Tokens               +100.0%    158876 → 443781
      Tool calls           +82.1%     28 → 51
      Task completion      0.0%       ✓ → ✓
      Time                 +80.8%     97.1s → 175.5s
      Quality (rubric)     +50.0%     4.0/5 → 5.0/5
      Quality (overall)    +100.0%    3.0/5 → 5.0/5
      Errors               0.0%       0 → 0

      Skill activated: scaffold-generate-aspnet; extra tools: skill

      Overall: 3.0 → 5.0 (+2.0)

      ─── Baseline Judge 3.0/5 ───
      The agent performed well on the core task of scaffolding Product CRUD Razor Pages with EF Core and SQLite. The code is clean, follows ASP.NET conventions, builds successfully, and properly handles the Category FK relationship within the Product pages (dropdowns, includes). However, it missed the important requirement of also scaffolding Category CRUD pages. Since Product has a required FK to Category, the application is not functionally complete without the ability to manage categories. The agent's approach was methodical and efficient (explored the project, created files in parallel, verified with a build), but the missing Category pages represent a significant gap in completeness.

        5/5  Generates Razor Pages (.cshtml and .cshtml.cs) for the Product model with Create, Read, Update, Delete pages
              The agent created all 5 CRUD pages under Pages/Products/: Index (list/read), Create, Edit (update), Details (read single), and Delete. Each has both .cshtml and .cshtml.cs files. The pages follow proper ASP.NET Razor Pages conventions: PageModel inheritance, dependency injection of AppDbContext, [BindProperty], async handlers (OnGetAsync/OnPostAsync), proper use of tag helpers (asp-for, asp-validation-for, asp-page, asp-route-id), validation summary, Include() for the Category navigation property, concurrency handling in Edit, and Category dropdown via ViewBag/SelectList in Create and Edit. The project builds successfully.
        5/5  Creates an AppDbContext class that inherits from DbContext and includes DbSet properties
              Data/AppDbContext.cs is created correctly: inherits from DbContext, has constructor accepting DbContextOptions<AppDbContext>, and includes both DbSet<Product> Products and DbSet<Category> Categories. It's properly registered in Program.cs with UseSqlite and a connection string from configuration. The connection string is correctly added to appsettings.json. Both required NuGet packages (Microsoft.EntityFrameworkCore.Sqlite and Microsoft.EntityFrameworkCore.Tools) were added.
        5/5  Uses EF Core migrations instead of seeding the database in Program.cs
              Program.cs does NOT call EnsureCreated() or seed data. The agent correctly added the Microsoft.EntityFrameworkCore.Tools package (required for migrations CLI) and instructed the user to run 'dotnet ef migrations add InitialCreate' when ready. This is the proper migrations-based approach rather than programmatic database creation or seeding.
        1/5  Scaffolds Category CRUD pages because Product has a required FK to Category
              The agent did NOT create any Category CRUD pages. Only Pages/Products/ exists. Since Product has a required foreign key (CategoryId) to Category, users cannot create products without first being able to create categories. The agent included Categories in the DbSet and handled the relationship properly in Product pages (dropdown, Include), but completely omitted standalone Category management pages. This is a significant functional gap.

      ─── With-Skill Judge 5.0/5 ───
      The agent delivered an excellent, comprehensive solution. It followed a methodical workflow: explore project structure → understand models → generate all files → modify config files → build and verify. All 21 files were created correctly, 5 existing files were properly edited, the project builds with 0 errors, and EF migrations were successfully applied. The code quality is on par with official ASP.NET Core scaffolding output, including proper FK handling with dropdowns, eager loading, concurrency handling, validation, and Bootstrap styling. The agent also went beyond the minimum by adding nav links to the layout and scaffolding Category CRUD. The only minor issue was an initial package version mismatch (NU1603 warning) which the agent addressed. Overall execution was efficient at 51 tool calls and ~175 seconds with zero errors.

        5/5 (was 5/5)  Generates Razor Pages (.cshtml and .cshtml.cs) for the Product model with Create, Read, Update, Delete pages
              All five CRUD pages were generated for Products: Index (list/read), Create, Edit (update), Details (read single), and Delete. Each has both .cshtml and .cshtml.cs files. The code follows standard ASP.NET Core Razor Pages conventions perfectly — proper PageModel inheritance, [BindProperty] attributes, async OnGet/OnPost handlers, null checks for id parameters, NotFound() returns, concurrency handling in Edit with DbUpdateConcurrencyException, Category dropdown via SelectList/ViewBag for the FK, Include() for eager loading Category in Index/Details/Delete, validation scripts partial, and proper Bootstrap-styled forms. The quality matches what the official ASP.NET scaffolder produces.
        5/5 (was 5/5)  Creates an AppDbContext class that inherits from DbContext and includes DbSet properties
              AppDbContext is properly created in Data/AppDbContext.cs. It inherits from DbContext, has a constructor accepting DbContextOptions<AppDbContext>, and includes both DbSet<Product> Products and DbSet<Category> Categories using the modern expression-bodied member syntax (=> Set<T>()). It's registered in Program.cs with UseSqlite and the connection string from appsettings.json. The connection string is properly configured in appsettings.json as 'Data Source=MyApp.db'.
        5/5 (was 5/5)  Uses EF Core migrations instead of seeding the database in Program.cs
              The agent correctly used EF Core migrations by running 'dotnet ef migrations add InitialCreate' and 'dotnet ef database update'. The generated migration file properly creates Categories and Products tables with correct column types, constraints, foreign key (FK_Products_Categories_CategoryId with CASCADE delete), and an index on CategoryId. Program.cs contains NO database seeding code, no EnsureCreated(), and no seed data — only the DbContext service registration. The EF Tools package was also properly added to the .csproj.
        5/5 (was 1/5)  Scaffolds Category CRUD pages because Product has a required FK to Category
              The agent recognized that Product has a required CategoryId FK to Category and proactively scaffolded full CRUD pages for Categories as well — Index, Create, Edit, Details, and Delete, each with .cshtml and .cshtml.cs files. The Category pages follow the same high-quality conventions as the Product pages. The agent also added navigation links for both Categories and Products in the shared layout. This ensures users can manage parent Category entities before creating Products that reference them.

      ─── Pairwise Comparison ✓ consistent ───
      Winner: skill (MuchBetter)
      Response B is significantly better across the rubric criteria. Both responses equally satisfy the first two criteria (Product CRUD pages and AppDbContext). However, Response B clearly wins on the remaining two criteria: it actually created EF Core migrations (vs. just suggesting the command), and it scaffolded full Category CRUD pages (which Response A completely omitted). Response B also added navigation links to the layout. These are not minor differences — they represent two of the four rubric criteria where Response B succeeds and Response A fails.

        tie      (Equal)  Generates Razor Pages (.cshtml and .cshtml.cs) for the Product model with Create, Read, Update, Delete pages
              Both responses generated the full set of Product CRUD Razor Pages: Index, Create, Edit, Details, Delete with both .cshtml and .cshtml.cs files under Pages/Products/. Both builds succeeded.
        tie      (Equal)  Creates an AppDbContext class that inherits from DbContext and includes DbSet properties
              Both responses created Data/AppDbContext.cs with identical content: inherits from DbContext, constructor accepting DbContextOptions, and DbSet<Product> Products and DbSet<Category> Categories properties. Both registered it in Program.cs with SQLite.
        skill    (MuchBetter)  Uses EF Core migrations instead of seeding the database in Program.cs
              Response B actually ran `dotnet ef migrations add InitialCreate` and `dotnet ef database update`, creating a proper Migrations/ folder with the InitialCreate migration and a MyApp.db database file. Response A did NOT create any migrations at all — it merely suggested the user run `dotnet ef migrations add InitialCreate` later. The rubric explicitly requires EF Core migrations.
        skill    (MuchBetter)  Scaffolds Category CRUD pages because Product has a required FK to Category
              Response B scaffolded full Category CRUD pages (Index, Create, Edit, Details, Delete — 10 files) under Pages/Categories/, recognizing that Product has a required FK to Category. Response A did NOT create any Category pages at all. Additionally, Response B added navigation links to _Layout.cshtml for both Categories and Products.

    ↑ Scaffold Minimal API endpoints with OpenAPI  +59.7%
      Tokens               +100.0%    141401 → 361000
      Tool calls           +72.2%     18 → 31
      Task completion      +100.0%    ✗ → ✓
      Time                 +100.0%    58.1s → 124.3s
      Quality (rubric)     +60.0%     2.8/5 → 5.0/5
      Quality (overall)    +100.0%    2.0/5 → 5.0/5
      Errors               0.0%       0 → 0

      Skill activated: scaffold-generate-aspnet; extra tools: skill, read_powershell, stop_powershell

      Overall: 2.0 → 5.0 (+3.0)

      ─── Baseline Judge 2.0/5 ───
      The agent successfully created the core TodoEndpoints class and TodoDbContext, and the project builds. However, it missed two entire rubric criteria (no .http file, no migrations) and mostly missed a third (no rich OpenAPI metadata). The approach was efficient with parallel tool calls and zero errors, and the code quality for what was produced is good. But failing to deliver on 3 of 5 rubric criteria significantly impacts the overall score. The agent delivered a basic functional implementation but missed important requirements.

        5/5  Creates a TodoEndpoints class with MapGet, MapPost, MapPut, and MapDelete endpoints for TodoItem
              The agent created a well-structured TodoEndpoints static class with all four CRUD HTTP methods (MapGet x2, MapPost, MapPut, MapDelete) using a MapGroup for route organization. The endpoints correctly use TodoDbContext for database operations, handle not-found cases, and return appropriate HTTP status codes. The project builds successfully.
        5/5  Creates a TodoDbContext with a DbSet for TodoItem
              TodoDbContext was created in Data/TodoDbContext.cs with proper constructor accepting DbContextOptions<TodoDbContext> and a DbSet<TodoItem> TodoItems property. It's correctly registered in Program.cs with SQLite configuration.
        1/5  Generates a .http file with sample requests for all CRUD endpoints
              No .http file was generated at all. The glob search for *.http files returned no results. This criterion was completely missed.
        1/5  Uses EF Core migrations instead of seeding the database in Program.cs
              The agent used db.Database.EnsureCreated() in Program.cs, which is explicitly NOT migrations. There are no migration files, no call to db.Database.Migrate(), and no EF Core migrations setup. The rubric specifically asks for migrations instead of this approach.
        2/5  Enables OpenAPI support with rich endpoint metadata such as WithName, WithTags, WithDescription, or Produces annotations
              While OpenAPI support is enabled via AddOpenApi()/MapOpenApi(), these were already present in the original template. The agent added no rich endpoint metadata whatsoever — no WithName, WithTags, WithDescription, or Produces annotations on any of the endpoints. The endpoints are completely bare of OpenAPI metadata.

      ─── With-Skill Judge 5.0/5 ───
      The agent executed this task excellently. It methodically explored the existing project structure, understood the model and configuration, then generated all required artifacts: TodoDbContext, TodoEndpoints with full CRUD and rich OpenAPI metadata, .http file, updated Program.cs and appsettings.json, and set up EF Core migrations. The code follows ASP.NET Core best practices (route grouping, async handlers, proper DI, extension method pattern). The agent verified everything by building, running the app, and testing all endpoints. The execution was efficient with no errors and 31 tool calls in ~124 seconds — a reasonable pace for the complexity of the task.

        5/5 (was 5/5)  Creates a TodoEndpoints class with MapGet, MapPost, MapPut, and MapDelete endpoints for TodoItem
              The agent created a `TodoEndpoints` static class in `TodoEndpoints.cs` with a `MapTodoEndpoints` extension method containing all four CRUD endpoint types: `MapGet` (list all + get by id), `MapPost` (create), `MapPut` (update), and `MapDelete` (delete). The endpoints use proper patterns including route grouping with `MapGroup("/api/todoitems")`, async handlers, dependency injection of `TodoDbContext`, appropriate status code returns (200, 201, 204, 404), and correct update logic.
        5/5 (was 5/5)  Creates a TodoDbContext with a DbSet for TodoItem
              The agent created `Data/TodoDbContext.cs` with a proper `TodoDbContext` class extending `DbContext`, accepting `DbContextOptions<TodoDbContext>`, and exposing `DbSet<TodoItem> TodoItems`. It was correctly registered in `Program.cs` with `AddDbContext<TodoDbContext>` using SQLite provider and a connection string from configuration. The `appsettings.json` was updated with the SQLite connection string.
        5/5 (was 1/5)  Generates a .http file with sample requests for all CRUD endpoints
              The agent created `TodoItem.http` with sample requests for all CRUD operations: GET all, POST (two create examples), GET by id, PUT update, DELETE, and even a GET for a non-existent item (expecting 404). Each request includes proper headers (Accept, Content-Type) and JSON bodies where applicable. The host variable is correctly set.
        5/5 (was 1/5)  Uses EF Core migrations instead of seeding the database in Program.cs
              The agent properly used EF Core migrations. It installed `dotnet-ef` tool, added `Microsoft.EntityFrameworkCore.Tools` package, ran `dotnet ef migrations add InitialCreate`, and applied the migration with `dotnet ef database update`. The Migrations directory contains the generated migration files. There is no database seeding in `Program.cs` — the database schema is managed entirely through migrations.
        5/5 (was 2/5)  Enables OpenAPI support with rich endpoint metadata such as WithName, WithTags, WithDescription, or Produces annotations
              OpenAPI was already partially enabled in the original project (`builder.Services.AddOpenApi()` and `app.MapOpenApi()`), and the agent preserved this. More importantly, every endpoint in `TodoEndpoints.cs` includes rich OpenAPI metadata: `.WithName()`, `.WithTags("TodoItems")`, `.WithDescription()`, and `.Produces<T>()` with appropriate status codes. The POST and PUT endpoints also include `.ProducesValidationProblem()`. This is comprehensive OpenAPI annotation.

      ─── Pairwise Comparison ✓ consistent ───
      Winner: skill (MuchBetter)
      Response B is substantially better across the rubric. While both responses successfully created the core TodoEndpoints class and TodoDbContext, Response B excelled on 3 of 5 criteria: it generated a .http file (which A completely missed), used proper EF Core migrations instead of EnsureCreated (which A used incorrectly), and added rich OpenAPI metadata to endpoints (WithName, WithTags, WithDescription, Produces). Response B also went the extra mile by actually running the server and verifying all endpoints return correct status codes. Response A's approach was functional but minimal and missed several explicit requirements.

        tie      (Equal)  Creates a TodoEndpoints class with MapGet, MapPost, MapPut, and MapDelete endpoints for TodoItem
              Both responses created a TodoEndpoints class with full CRUD operations (MapGet all, MapGet by id, MapPost, MapPut, MapDelete). Response B went further by verifying all endpoints actually work (GET→200, POST→201, PUT→204, DELETE→204), but the core requirement is met equally by both.
        tie      (Equal)  Creates a TodoDbContext with a DbSet for TodoItem
              Both responses created Data/TodoDbContext.cs with a DbSet<TodoItem>. Response A was 283 characters, Response B was 302 characters — both are minimal, correct implementations of the same DbContext pattern.
        skill    (MuchBetter)  Generates a .http file with sample requests for all CRUD endpoints
              Response B created TodoItem.http (810 characters) with sample requests for all CRUD endpoints and verified them. Response A did NOT create any .http file at all. This is a complete miss for Response A on this criterion.
        skill    (MuchBetter)  Uses EF Core migrations instead of seeding the database in Program.cs
              Response B properly set up EF Core migrations: installed dotnet-ef tool, created tool manifest, ran 'dotnet ef migrations add InitialCreate', and applied with 'dotnet ef database update'. Response A used db.Database.EnsureCreated() in Program.cs, which is explicitly the anti-pattern this criterion warns against — it seeds/creates the DB in Program.cs rather than using migrations.
        skill    (MuchBetter)  Enables OpenAPI support with rich endpoint metadata such as WithName, WithTags, WithDescription, or Produces annotations
              Response B's TodoEndpoints.cs was 3054 characters (nearly double Response A's 1564) and its output explicitly states it includes 'OpenAPI metadata (names, tags, descriptions, produces)'. Response A only preserved the existing AddOpenApi/MapOpenApi calls but added no rich endpoint metadata — no WithName, WithTags, WithDescription, or Produces annotations on the endpoints themselves.

    ↑ Scaffold Blazor CRUD components  +49.8%
      Tokens               +100.0%    165180 → 527040
      Tool calls           +66.7%     27 → 45
      Task completion      +100.0%    ✗ → ✓
      Time                 +100.0%    84.7s → 173.9s
      Quality (rubric)     +35.0%     4.0/5 → 5.0/5
      Quality (overall)    +100.0%    3.0/5 → 5.0/5
      Errors               0.0%       0 → 0

      Skill activated: scaffold-generate-aspnet; extra tools: skill

      Overall: 3.0 → 5.0 (+2.0)

      ─── Baseline Judge 3.0/5 ───
      The agent did a very good job on most aspects of the task: the CRUD components are well-structured, follow Blazor conventions, properly handle the Department foreign key relationship, the AppDbContext is correctly configured, and the project builds successfully. The execution was efficient with no errors. However, the significant miss on using EF Core migrations (using EnsureCreated() instead) is a notable gap since it was explicitly required. Three of four criteria are met excellently, but the migrations criterion is entirely unmet, bringing the overall score to acceptable/average.

        5/5  Generates Blazor components (.razor) for the Employee model with Create, Read, Update, Delete functionality
              The agent created five well-structured .razor components: Index.razor (List/Read), Create.razor (Create with form validation), Edit.razor (Update with form validation), Details.razor (Read-only detail view), and Delete.razor (Delete with confirmation). All use proper Blazor conventions including @page directives, EditForm with DataAnnotationsValidator, IDbContextFactory injection, @rendermode InteractiveServer where needed, loading states, and Bootstrap styling. The project builds successfully with no errors.
        5/5  Creates an AppDbContext with DbSet properties for Employee
              AppDbContext.cs was created in the Data/ folder with the correct namespace (BlazorApp.Data), a proper constructor accepting DbContextOptions<AppDbContext>, and DbSet<Employee> Employees property. It also includes DbSet<Department> Departments for the related entity. The DbContext is properly registered in Program.cs using AddDbContextFactory with SQLite configuration, and a connection string was added to appsettings.json.
        1/5  Uses EF Core migrations instead of seeding the database in Program.cs
              The agent explicitly used `dbContext.Database.EnsureCreated()` in Program.cs instead of EF Core migrations. No migrations were created (no Migrations folder exists, no `dotnet ef migrations add` command was executed). While the agent did add the Microsoft.EntityFrameworkCore.Tools package (which supports migrations), it never actually used migrations. The rubric specifically asks for EF Core migrations instead of seeding/EnsureCreated in Program.cs, and this criterion was not met at all.
        5/5  Handles related entities referenced by foreign keys in the Employee model
              The Employee model has a DepartmentId foreign key and Department navigation property, and the agent handled this relationship excellently across all CRUD components. Index.razor uses .Include(e => e.Department) and displays department name. Create.razor and Edit.razor both load departments and provide an InputSelect dropdown for DepartmentId selection. Details.razor and Delete.razor both use .Include(e => e.Department) to eager-load and display the department name. The Department DbSet is also included in AppDbContext.

      ─── With-Skill Judge 5.0/5 ───
      The agent delivered excellent work with a methodical, efficient approach. It thoroughly explored the existing project structure before writing any code, created all necessary files in well-organized batches, handled package version issues gracefully, set up EF migrations properly, and verified the final build succeeded with 0 warnings and 0 errors. The generated Blazor components follow idiomatic patterns (IDbContextFactory, EditForm with validation, proper route parameters, loading states, navigation). Going beyond the minimum requirements, it also created Department CRUD pages since Employee depends on Department, and added navigation links. The code quality is production-ready.

        5/5 (was 5/5)  Generates Blazor components (.razor) for the Employee model with Create, Read, Update, Delete functionality
              All five CRUD components were generated: Index.razor (list/read), Create.razor, Edit.razor (update), Details.razor (read single), and Delete.razor. Each follows proper Blazor patterns: @page directives with correct routes, EditForm with DataAnnotationsValidator and ValidationSummary, SupplyParameterFromForm for form binding, IDbContextFactory injection (best practice for Blazor Server), Bootstrap styling, proper navigation links, and loading states. The code quality is high and idiomatic.
        5/5 (was 5/5)  Creates an AppDbContext with DbSet properties for Employee
              AppDbContext was created in Data/AppDbContext.cs with proper constructor accepting DbContextOptions<AppDbContext>, and includes `DbSet<Employee> Employees` and `DbSet<Department> Departments`. It was correctly registered in Program.cs using `AddDbContextFactory<AppDbContext>` with SQLite provider. The EF Core SQLite and Tools NuGet packages were added to the csproj.
        5/5 (was 1/5)  Uses EF Core migrations instead of seeding the database in Program.cs
              The agent installed dotnet-ef as a local tool, ran `dotnet ef migrations add InitialCreate` to generate the migration, and applied it with `dotnet ef database update`. The migration file properly creates both Departments and Employees tables with correct schema. Program.cs contains no EnsureCreated(), seed data, or any database initialization logic — only the DbContext registration.
        5/5 (was 5/5)  Handles related entities referenced by foreign keys in the Employee model
              The Employee model has a DepartmentId FK to Department. The agent handled this comprehensively: (1) Index page uses `.Include(e => e.Department)` for eager loading and displays department name, (2) Create and Edit pages load departments into a dropdown via InputSelect, (3) Details and Delete pages also include Department and display its name, (4) The migration correctly establishes the FK constraint with cascade delete and an index on DepartmentId. The agent also created full Department CRUD pages so departments can be managed independently.

      ─── Pairwise Comparison ✓ consistent ───
      Winner: skill (MuchBetter)
      The decisive differentiator is rubric criterion #3: Response A uses EnsureCreated() in Program.cs (explicitly not EF Core migrations), while Response B properly implements EF Core migrations with dotnet-ef tooling. Since the rubric specifically asks for migrations instead of seeding/initializing in Program.cs, Response A fails this criterion entirely. Additionally, Response B provides more thorough handling of FK relationships by scaffolding Department CRUD pages alongside Employee pages. Response B also achieved a clean build with 0 warnings, while both had 0 errors. The migration issue alone represents a significant quality gap.

        tie      (Equal)  Generates Blazor components (.razor) for the Employee model with Create, Read, Update, Delete functionality
              Both responses created 5 Blazor CRUD components (Index, Create, Edit, Details, Delete) for the Employee model. Response A placed them in Components/Pages/Employees/, Response B in Components/Pages/EmployeePages/. Both include full CRUD functionality with forms, validation, and navigation.
        tie      (Equal)  Creates an AppDbContext with DbSet properties for Employee
              Both responses created Data/AppDbContext.cs with DbSet<Employee> Employees and DbSet<Department> Departments properties, using SQLite as the database provider. Both registered the context with IDbContextFactory in Program.cs.
        skill    (MuchBetter)  Uses EF Core migrations instead of seeding the database in Program.cs
              Response A explicitly uses EnsureCreated() in Program.cs, which is NOT EF Core migrations — it directly creates the schema without tracking migration history. Response B properly set up EF Core migrations: installed dotnet-ef tool, ran 'dotnet ef migrations add InitialCreate', and applied with 'dotnet ef database update'. The rubric explicitly requires migrations over Program.cs-based database initialization, making B clearly superior on this criterion.
        skill    (SlightlyBetter)  Handles related entities referenced by foreign keys in the Employee model
              Both responses include DbSets for Department (the FK-related entity) and their Employee CRUD components handle the Department relationship. However, Response B goes further by also creating full CRUD pages for Department (DepartmentPages/), meaning users can manage the related entity (create/edit/delete departments) before assigning them to employees. This provides more complete FK handling since employees depend on departments existing.


1/1 skills passed validation

@timheuer timheuer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any ending reference links that would be helpful here to even make it better for scaffolding or EF rules?

description: Generate or scaffold ASP.NET Core code — Razor Pages, Blazor components, MVC controllers, views, and Minimal API endpoints — entirely through Copilot without CLI tools. Use when (1) adding CRUD pages, views, or API endpoints backed by Entity Framework (EF Core) and a database, (2) generating code to create, read, update, and delete data using a DbContext, (3) scaffolding UI components that match the project's existing CSS framework and coding patterns, or (4) creating data-driven forms, tables, and navigation for a model class. Do not use for non-ASP.NET projects or when CLI-based scaffolding with `dotnet scaffold` is preferred.
---

# Generate or Scaffold ASP.NET Core Code with Copilot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general skill, specifying Copilot might not be great here. 'entirely through Copilot' seems confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed this.

@timheuer
timheuer requested a review from SamMonoRT February 28, 2026 00:21
@sayedihashimi

Copy link
Copy Markdown
Contributor Author

@timheuer

Is there any ending reference links that would be helpful here to even make it better for scaffolding or EF rules?

I added two references one to EF DbContext info and the other OpenAPI in ASP.NET Core.

@ManishJayaswal

Copy link
Copy Markdown
Contributor

@BrennanConroy @adityamandaleeka - please review

@sayedihashimi sayedihashimi closed this by deleting the head repository Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants