Chapter 01 · EF Core Foundations, .NET Integration, Providers, and the First Lab
EF Core 10 and .NET 10: LTS Baseline, Package Compatibility, and Upgrade Discipline
Turn “EF Core 10” into an explicit support and compatibility contract covering .NET runtime/SDK, aligned EF packages, providers, dotnet-ef, stable-versus-preview channels, and reproducible upgrade evidence.
Learning outcomes
A production incident can begin with a version sentence that sounds harmless: “we are on EF Core 10.” That statement omits the EF patch, provider patch, design-time tool, .NET runtime, SDK feature band, database engine, and transitive ADO.NET driver. ServiceHub will make those dimensions explicit before any migration or deployment is trusted.
Explain why EF Core 10 is an LTS major release and why the supported 10.0.x patch—not merely the major number—belongs in environment evidence.
Distinguish the .NET SDK used to build from the .NET runtime used to execute, and read SDK feature-band versions correctly.
Distinguish EF runtime packages, provider packages, Microsoft.EntityFrameworkCore.Design, and dotnet-ef instead of treating them as one component.
Detect target-framework and package-major mismatches before they become migration or runtime surprises.
Create a version manifest and upgrade discipline that keeps stable EF Core 10 separate from EF Core 11 previews.
Microsoft documents EF Core 10 as LTS through 10 November 2028. The current stable EF Core and dotnet-ef patch is 10.0.11. The current .NET 10 runtime patch is 10.0.11. Microsoft’s .NET 10 download page lists SDK 10.0.400 as the newest SDK feature band; SDK 10.0.111 is also listed but is not the newest SDK overall. Re-check these values whenever a later chapter is generated.
1. Major, minor, patch, runtime, and SDK are different coordinates
EF Core 10 is the major product line. 10.0.11 is a servicing patch in that line. EF Core 10 was released in November 2025 as a Long Term Support (LTS) release and requires the .NET 10 SDK to build and .NET 10 runtime to run. It does not run on earlier .NET versions or .NET Framework. A stable 10.0.x update is therefore a servicing move inside the course baseline, while EF Core 11 is a different major line with preview builds in 2026.
The .NET version has two related but distinct surfaces. The
runtime executes compiled applications. The
SDK includes compilers, MSBuild, templates, the
CLI, and a runtime. SDK numbers use feature bands, so
10.0.400 does not mean “runtime 10.0.40.” The
current SDK 10.0.400 includes .NET runtime 10.0.11. Treat SDK
and runtime as separate evidence fields.
| Component | Current chapter baseline | Why it matters |
|---|---|---|
| Target framework | net10.0 |
EF Core 10 targets .NET 10; target framework controls compile-time compatibility. |
| .NET runtime | 10.0.11 |
Execution/security servicing state. |
| .NET SDK | 10.0.400 current newest feature band |
Build tooling; multiple feature bands can coexist. |
| EF runtime/provider packages | 10.0.11 |
Runtime ORM/provider behavior. |
| Design package | 10.0.11 |
Design-time services used by tooling. |
| dotnet-ef tool | 10.0.11 |
Migration/scaffolding CLI; separate .NET tool install. |
2. Inspect the machine before changing the project
dotnet --version reports the SDK selected for the
current directory, which can be influenced by
global.json. It does not list every installed SDK
or runtime. Use the broader inventory commands when diagnosing a
build that behaves differently across machines or CI agents.
dotnet --versiondotnet --infodotnet --list-sdksdotnet --list-runtimes
A representative August 2026 workstation might select
10.0.400 while also having
10.0.111 installed. That is not inherently a
conflict. The selected SDK depends on the working directory,
installed SDKs, global.json, and roll-forward
policy. Capture the actual output in CI evidence instead of
assuming the newest installed SDK is always selected.
The .NET 10.0.11 download page marks the release as a security patch. A reproducible course can pin versions for teaching, but production servicing policy must still consume supported security updates deliberately.
3. Understand the EF package family
Microsoft.EntityFrameworkCore contains core ORM
services. Relational providers such as
Microsoft.EntityFrameworkCore.Sqlite and
Microsoft.EntityFrameworkCore.SqlServer depend on
EF’s relational infrastructure and add database-specific
services.
Microsoft.EntityFrameworkCore.Design supplies
design-time services used by tooling. dotnet-ef is
a .NET tool installed globally or locally; it is not the same
thing as a project PackageReference.
Microsoft-shipped EF packages should normally remain on the same servicing patch. A project that explicitly pins incompatible majors is not “more flexible”; it creates a dependency graph whose APIs and design-time services were not released as one tested set.
<ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.11" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.11"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference></ItemGroup>
The provider brings the EF dependencies it needs. You do not
need to add Microsoft.EntityFrameworkCore directly
unless your package structure or central package management has
a reason to do so. Fewer redundant explicit references make
dependency intent easier to review.
4. Provider compatibility is a contract, not a successful restore
EF Core’s provider documentation warns that providers generally do not work across major EF versions. Microsoft’s SQL Server and SQLite providers list support for EF Core 10. Third-party providers are released independently, so a provider’s latest stable package, supported database versions, license, and support policy must be checked at the time you choose it.
A NuGet package restoring successfully is only dependency-resolution evidence. It does not prove every LINQ translation, migration operation, database type, JSON feature, concurrency token, or DDL operation behaves the same as another provider. Provider-specific chapters will validate behavior against each engine rather than infer portability from API similarity.
5. Deliberately wrong approach: target .NET 9 with EF Core 10
The clearest compatibility failure is a target-framework
mismatch. EF Core 10 requires .NET 10. If a project targets
net9.0 and you add EF Core 10, restore cannot make
the package compatible merely because a .NET 10 SDK is
installed.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net9.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.11" /> </ItemGroup></Project>
NuGet reports an incompatibility such as
NU1202 because the package targets .NET 10 while
the project targets .NET 9. The repair is not to suppress the
diagnostic. Either keep that application on an EF version
compatible with its supported target framework, or intentionally
upgrade the application to net10.0, test its
dependencies, and deploy a .NET 10 runtime.
<TargetFramework>net10.0</TargetFramework>
6. Preview availability does not change the course baseline
NuGet currently exposes EF Core 11 preview packages alongside stable 10.0.11. A package manager can therefore show a numerically higher version even though the course is intentionally built on the supported EF Core 10 LTS line. Preview APIs can change and carry a different support posture; they must not silently enter a production or teaching baseline through an “include prerelease” update.
dotnet list packagedotnet list package --outdateddotnet tool list --localdotnet tool list --global
In automated dependency tooling, configure stable-channel policy explicitly. A human reviewer should be able to see whether a pull request is a 10.0.x servicing update or a major/pre-release transition requiring migration analysis.
7. Pin the SDK deliberately with global.json when reproducibility requires it
A repository can use global.json to request an SDK
version and roll-forward behavior. This is useful when a course
or CI pipeline must avoid silently moving between SDK feature
bands. It is not a substitute for patching: the pin itself must
be maintained.
{ "sdk": { "version": "10.0.400", "rollForward": "latestPatch", "allowPrerelease": false }}
latestPatch keeps selection inside the requested
feature band. Organizations that deliberately accept newer
feature bands can choose a different roll-forward policy after
testing. Always verify the resulting selection with
dotnet --version in the exact repository directory.
8. Build a machine-readable environment manifest
For ServiceHub, record enough data that another developer can explain a translation or migration difference without guessing. A small text artifact captured by CI is often more useful than a screenshot.
dotnet --versiondotnet --infodotnet list package --include-transitivedotnet tool list --localdotnet ef --version
For database-backed tests, add provider/database evidence too: SQLite library version, SQL Server build, PostgreSQL server version, MySQL/MariaDB version, container image digest, and OS/architecture where relevant. The same C# source can legitimately produce different SQL across provider or database versions.
9. Hands-on lab: create and break a version contract safely
Use a disposable directory. The failure is a package/target-framework experiment only; it does not touch a database.
mkdir ef-version-contractcd ef-version-contractdotnet new globaljson --sdk-version 10.0.400 --roll-forward latestPatchdotnet new console -n VersionProbe -f net10.0cd VersionProbedotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 10.0.11dotnet add package Microsoft.EntityFrameworkCore.Design --version 10.0.11dotnet restoredotnet builddotnet list package
Verify the project builds and all Microsoft EF package versions
resolve to the 10.0.11 line. Next, in a second disposable
project, target net9.0 and attempt to add the same
SQLite 10.0.11 provider. Observe the restore incompatibility,
then delete the broken project rather than weakening version
checks.
cd ..dotnet new console -n WrongTarget -f net9.0cd WrongTargetdotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 10.0.11# Expected: package/target-framework incompatibility; do not suppress it.
Verification checklist
- The supported project targets
net10.0. - The selected SDK is visible and matches repository policy.
- EF Core, provider, Design, and dotnet-ef are treated as separate versioned components.
- The deliberately wrong project fails for a reason you can explain.
- No EF Core 11 preview package appears in the stable course project.
Check your understanding
- Why can SDK 10.0.400 run applications on runtime 10.0.11 without those numbers matching digit-for-digit?
- What is the difference between Microsoft.EntityFrameworkCore.Design and dotnet-ef?
- Does a successful third-party provider package restore prove EF Core 10 compatibility?
- Why is “latest version” ambiguous when previews exist?
- What evidence would you capture before investigating a provider-specific regression?
Review the answers
The SDK and runtime use different version schemes. SDK feature-band numbers identify build tooling; an SDK includes a particular runtime servicing patch.
Design is a project package that exposes design-time services. dotnet-ef is a separately installed CLI tool that invokes those services for tasks such as migrations and scaffolding.
No. Restore proves dependency resolution only. Provider documentation, supported EF/database versions, and behavior tests are still required.
A preview major can have a higher semantic version than the current supported stable line. Upgrade policy must distinguish stable servicing from preview/major transitions.
Capture target framework, selected/installed SDKs, runtime, EF packages including transitives, dotnet-ef, provider and ADO.NET driver versions, database build, and the failing generated SQL/log/exception.
10. Upgrade discipline for production teams
Servicing updates should be routine but observable: update aligned packages, restore from trusted sources, build, run unit/integration/migration tests, inspect generated SQL for sensitive paths, validate provider/database support, and deploy through normal rollback controls. A major EF upgrade deserves a separate breaking-change review and provider readiness check.
Do not solve version drift by letting every workstation float independently, and do not freeze a vulnerable runtime forever in the name of reproducibility. Reproducibility means the version-selection policy is explicit and reviewable; security servicing means that policy is maintained.
Lesson 3 turns this version contract into a working toolchain:
local versus global dotnet-ef, provider selection,
the Design package, restore/build checks, and common design-time
failures.
Authoritative references
- What's New in EF Core 10 — EF Core 10 LTS dates and .NET 10 requirement
- .NET 10 downloads — current runtime/security patch and SDK feature bands
- Database providers — provider compatibility and maintainer guidance
- Installing Entity Framework Core — runtime/provider packages and EF tooling
- EF Core .NET CLI tools — dotnet-ef installation, verification, and design-time commands
- Microsoft.EntityFrameworkCore 10.0.11 — current stable EF Core package metadata
- dotnet-ef 10.0.11 — current stable EF CLI tool package metadata