Logo Microsoft
Données & RechercheSûr100100/100

Migrating Ef6 Code First To Ef Core (Microsoft)

Migrates Entity Framework 6 Code-First projects to EF Core. Use when upgrading projects that already use DbContext with Code-First models (no EDMX files) and need to move to EF Core. Triggers for "migrate EF6 to EF Core", "upgrade Entity Framework to EF Core", "convert EF6 Code-First to EF Core", "replace EntityFramework package with EF Core", or "modernize Entity Framework". Also relevant when encountering EF6-specific APIs like EntityTypeConfiguration, DbModelBuilder, Database.SetInitializer, or HasDatabaseGeneratedOption during .NET modernization.

ou envoie-le directement à ton agent.

Installer dans ton projet

$ curl -fsSL https://arboristhree.xyz/cli/install-skill.mjs -o /tmp/arboris-install-skill.mjs && node /tmp/arboris-install-skill.mjs migrating-ef6-code-first-to-ef-core__microsoft-upgrade-agent-plugins__plugins-upgrade-agent-extenders-upgrade-dotnet-upgrade-skills-lazy-data-bf8f3f734fcf
Logo Microsoft
Microsoft
microsoft/upgrade-agent-plugins
Contenu à copier
---

name: migrating-ef6-code-first-to-ef-core
description: >
  Migrates Entity Framework 6 Code-First projects to EF Core. Use when upgrading projects that
  already use DbContext with Code-First models (no EDMX files) and need to move to EF Core. Triggers
  for "migrate EF6 to EF Core", "upgrade Entity Framework to EF Core", "convert EF6 Code-First to
  EF Core", "replace EntityFramework package with EF Core", or "modernize Entity Framework". Also
  relevant when encountering EF6-specific APIs like EntityTypeConfiguration, DbModelBuilder,
  Database.SetInitializer, or HasDatabaseGeneratedOption during .NET modernization.
metadata:
  origin: Microsoft
  traits: .NET|CSharp|VisualBasic|DotNetCore
---


# EF6 Code-First to EF Core Migration

## Overview

Migrates Entity Framework 6 Code-First projects to EF Core. This skill covers projects that already use `DbContext` with fluent or data-annotation-based models — no EDMX files involved.

> **Scope:** This skill targets EF6 Code-First projects (no `.edmx` files). For EDMX-based projects (Database-First/Model-First), use the `migrating-edmx-to-code-first` skill instead. For DbContext registration and DI setup during ASP.NET Core migration, also apply the `migrating-ef-dbcontext` skill — it is complementary to this one.

## Workflow

```
Migration Progress:
- [ ] Step 1: Assess EF6 usage
- [ ] Step 2: Swap NuGet packages
- [ ] Step 3: Update namespaces
- [ ] Step 4: Migrate DbContext and configuration
- [ ] Step 5: Migrate entity configurations
- [ ] Step 6: Handle breaking API changes
- [ ] Step 7: Migrate migrations history
- [ ] Step 8: Validate
```

### Step 1: Assess EF6 Usage

1. Confirm the project uses EF6 Code-First (has a `DbContext` subclass, no `.edmx` files)
2. List all `DbContext` subclasses and their `DbSet<T>` properties
3. Find `EntityTypeConfiguration<T>` classes and `OnModelCreating` overrides
4. Search for EF6-specific APIs: `Database.SetInitializer`, `DbModelBuilder`, `HasDatabaseGeneratedOption`, `Map()`, `MapToStoredProcedures()`
5. Check for custom conventions (`IConvention`, `Convention`)
6. Note any raw SQL usage: `Database.SqlQuery<T>()`, `Database.ExecuteSqlCommand()`
7. Check for the EF6 `Configuration` class generated by `Enable-Migrations` (typically in `Migrations/Configuration.cs`) — this will be removed
8. Confirm with the user before proceeding: if the project targets .NET Framework, advise upgrading to .NET 8 or later and updating EntityFramework to 6.5.1 first

### Step 2: Swap NuGet Packages

Remove the EF6 package and add EF Core packages matching the target framework.

```xml
<!-- Remove -->
<PackageReference Include="EntityFramework" />

<!-- Add (choose the appropriate database provider) -->
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" />
```

Use the EF Core major version that matches the project's target framework (e.g., EF Core 8.x for .NET 8, EF Core 10.x for .NET 10). Use the **managing-package-references** skill to add these packages — it handles version determination, CPM detection, and NuGet feed lookup.

### Step 3: Update Namespaces

Replace all `System.Data.Entity` usings with `Microsoft.EntityFrameworkCore`. Note that `System.Data.Entity.Validation` and `System.Data.Entity.Core.Objects` are removed entirely in EF Core — replace with custom validation and DbContext APIs respectively.

### Step 4: Migrate DbContext and Configuration

- Change constructor to accept `DbContextOptions<T>` instead of a connection string name
- Change `OnModelCreating` parameter from `DbModelBuilder` to `ModelBuilder`

**Database initializers:** EF Core does not support `Database.SetInitializer` or the `MigrateDatabaseToLatestVersion` initializer. Remove all initializer calls and convert seed logic to `HasData()` in `OnModelCreating` or a separate seed method called at startup. Also delete the EF6 `Configuration` class (typically `Migrations/Configuration.cs`) generated by `Enable-Migrations` — it has no equivalent in EF Core.

### Step 5: Migrate Entity Configurations

- Convert `EntityTypeConfiguration<T>` to `IEntityTypeConfiguration<T>` (add `Configure(EntityTypeBuilder<T>)` method, prefix all calls with `builder.`)
- Replace `HasRequired`/`HasOptional` with `HasOne` + `.IsRequired()`, and `WithRequired`/`WithOptional` with `WithOne` + `.IsRequired()`
- Replace `WillCascadeOnDelete(false)` with `OnDelete(DeleteBehavior.Restrict)`
- Replace `HasDatabaseGeneratedOption`:
  - `DatabaseGeneratedOption.Identity` → `ValueGeneratedOnAdd()` (database-generated IDs)
  - `DatabaseGeneratedOption.Computed` → `ValueGeneratedOnAddOrUpdate()` (computed columns)
  - `DatabaseGeneratedOption.None` → Check if you manually assign IDs before `Add()`. If yes, use `ValueGeneratedNever()`. If no (or using custom HiLo generator), use `ValueGeneratedOnAdd()` or EF Core's built-in `UseHiLo()` to avoid tracking conflicts from duplicate default IDs
- Replace `Map(m => m.ToTable("Name"))` with `ToTable("Name")` directly
- `HasMany().WithMany()` requires EF Core 5.0+. For join tables with payload columns, explicit join entity configuration is still required
- `MapToStoredProcedures()` is removed — use `FromSql()` or `ExecuteSql()`
- `modelBuilder.Conventions.Remove<T>()` is removed — override `ConfigureConventions(ModelConfigurationBuilder)` on the `DbContext` to add, remove, or replace conventions

**Decimal property precision:** EF6 automatically mapped `decimal` properties to `decimal(18,2)`. EF Core requires explicit precision configuration to avoid silent data truncation:

```csharp
// EF6 - automatic precision
public decimal Price { get; set; }  // Became decimal(18,2) in database

// EF Core - must specify precision
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>()
        .Property(p => p.Price)
        .HasPrecision(18, 2);  // Or use [Column(TypeName = "decimal(18,2)")]
}
```

**Register configurations:** Replace `modelBuilder.Configurations.Add(...)` with `modelBuilder.ApplyConfiguration(...)` or use `modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly)` to apply all at once.

### Step 6: Handle Breaking API Changes

**Raw SQL:** Replace `Database.SqlQuery<T>()` with `Set<T>().FromSql()` and `Database.ExecuteSqlCommand()` with `Database.ExecuteSql()`. Use interpolated strings (`$"..."`) for automatic parameterization — do not use string concatenation, which bypasses EF Core's parameterization and creates SQL injection vulnerabilities.

**Lazy loading:** EF Core disables lazy loading by default.
- Option 1: Install `Microsoft.EntityFrameworkCore.Proxies`, call `UseLazyLoadingProxies()`
- Option 2 (preferred): Use explicit `.Include()` for eager loading

**Complex types:** In EF Core 7 and earlier, `[ComplexType]` → `OwnsOne()`. EF Core 8+ reintroduces native support — use `ComplexProperty()` instead.

**Validation:** EF Core does not call `IValidatableObject.Validate()` on `SaveChanges()`. Add validation in the application layer or override `SaveChanges()` to call it explicitly.

### Step 7: Migrate Migrations History

Advise the user to apply all pending EF6 migrations to their database before starting the EF Core migration — this is a manual prerequisite. Once confirmed:

1. Delete the existing `Migrations/` folder (contains EF6 `DbMigration` classes and the `Configuration` class generated by `Enable-Migrations`)
2. Create a baseline EF Core migration. Present the command and offer to run it with user confirmation:

```powershell
dotnet ef migrations add InitialCreate
```

3. **Before marking the migration as applied, the user must verify that the existing database schema matches the EF Core model.** The user should review the generated migration file (`InitialCreate`) and confirm it reflects their current schema — not new changes. If the migration contains unexpected schema alterations, applying it could cause data loss. Only proceed once the user confirms the migration is a clean baseline.

4. Once verified, mark the migration as applied without running it. **Always pause and confirm with the user before executing database-modifying commands**, even in auto-execute mode — this connects to a live database:

```powershell
dotnet ef database update
```

Alternatively, to avoid connecting to the database directly, generate an idempotent SQL script:

```powershell
dotnet ef migrations script --idempotent --output mark-migration.sql
```

Advise the user to review the generated script and apply **only** the `INSERT INTO __EFMigrationsHistory` statement to their database. This registers the migration as applied without modifying the schema.

### Step 8: Validate

Compilation alone is not sufficient. Many EF6→EF Core differences only surface at runtime.

**LLM responsibilities (automated):**
1. Build the project and fix compilation errors
2. Confirm no EF6 artifacts remain (`System.Data.Entity` namespaces, `EntityFramework` package reference, `Migrations/Configuration.cs`)
3. Run existing unit tests

**User responsibilities (require database access and manual verification):**
4. Test CRUD operations against the database
5. Verify navigation property loading works as expected (eager vs lazy)
6. Validate change tracking behavior matches expectations (Added, Modified, Deleted states)
7. If stored procedures were migrated, test `FromSql`/`ExecuteSql` results
8. Compare query results with the EF6 version for any complex LINQ queries

Present items 4–8 as a checklist for the user — the LLM cannot validate runtime database behavior.

## Success Criteria

- `EntityFramework` NuGet package removed, EF Core packages added
- All `System.Data.Entity` namespaces replaced with `Microsoft.EntityFrameworkCore`
- `DbContext` constructor accepts `DbContextOptions`
- All `EntityTypeConfiguration<T>` classes converted to `IEntityTypeConfiguration<T>`
- Fluent API calls updated (`HasRequired` → `HasOne`, etc.)
- Raw SQL calls migrated to `FromSql`/`ExecuteSql`
- Lazy loading strategy decided and configured
- Complex types converted to owned entities or complex properties
- Database initializers and EF6 `Configuration` class removed, seed data migrated
- EF Core migrations baseline created
- Project builds, tests pass, queries return correct results
- Adding a new EF Core migration produces one without any operations (model matches database)
- No secrets are stored in plain text
Colle ce Markdown dans ton agent ou utilise les boutons ci-dessus pour l’écrire dans ton projet.

Ce que fait Migrating Ef6 Code First To Ef Core (Microsoft)

[ ] Step 1: Assess EF6 usage
[ ] Step 2: Swap NuGet packages
[ ] Step 3: Update namespaces
[ ] Step 4: Migrate DbContext and configuration

Comment utiliser Migrating Ef6 Code First To Ef Core (Microsoft)

1
Copie le prompt
Un clic copie le prompt packagé (ou l'envoie à ton agent).
2
L'agent installe le skill
Il ajoute le SKILL.md et ses ressources à ton projet.
3
Activation automatique
Le skill s'active dès que le contexte correspond.

Déclencheurs pour Migrating Ef6 Code First To Ef Core (Microsoft)

Dis simplement à ton agent quelque chose comme :

Applique le skill migrating-ef6-code-first-to-ef-core__microsoft-upgrade-agent-plugins__plugins-upgrade-agent-extenders-upgrade-dotnet-upgrade-skills-lazy-data-bf8f3f734fcf à cette tâche
Utilise migrating-ef6-code-first-to-ef-core__microsoft-upgrade-agent-plugins__plugins-upgrade-agent-extenders-upgrade-dotnet-upgrade-skills-lazy-data-bf8f3f734fcf pour améliorer cette implémentation
Passe en revue ce sujet avec migrating-ef6-code-first-to-ef-core__microsoft-upgrade-agent-plugins__plugins-upgrade-agent-extenders-upgrade-dotnet-upgrade-skills-lazy-data-bf8f3f734fcf

Skills liés à Migrating Ef6 Code First To Ef Core (Microsoft)