Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions entity-framework/core/cli/dbcontext-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
title: Design-time DbContext Creation - EF Core
description: Strategies for creating a design-time DbContext with Entity Framework Core
author: SamMonoRT
ms.date: 10/27/2020
ms.date: 08/05/2026
uid: core/cli/dbcontext-creation
---
# Design-time DbContext Creation

Some of the EF Core Tools commands (for example, the [Migrations][1] commands) require a derived `DbContext` instance to be created at design time in order to gather details about the application's entity types and how they map to a database schema. In most cases, it is desirable that the `DbContext` thereby created is configured in a similar way to how it would be [configured at run time][2].

There are various ways the tools try to create the `DbContext`:
There are various ways the tools try to create the `DbContext`. If an [`IDesignTimeDbContextFactory<TContext>`](#from-a-design-time-factory) is found, the tools use it instead of the other creation patterns. A design-time factory is the recommended pattern for a [separate migrations project](xref:core/managing-schemas/migrations/projects) and for applications whose startup project is platform-specific.

## From application services

Expand All @@ -34,7 +34,9 @@ You can also tell the tools how to create your DbContext by implementing the <xr

[!code-csharp[Main](../../../samples/core/Miscellaneous/CommandLine/BloggingContextFactory.cs#BloggingContextFactory)]

A design-time factory can be especially useful if you need to configure the `DbContext` differently for design time than at run time, if the `DbContext` constructor takes additional parameters are not registered in DI, if you are not using DI at all, or if for some reason you prefer not to have a `CreateHostBuilder` method in your ASP.NET Core application's `Main` class.
A design-time factory can be especially useful if the context constructor has dependencies that aren't registered in DI, if you aren't using DI, or if the application startup project can't be executed by the tools.

Configure the same provider, model options, and migrations assembly at design time that the application uses at run time. Otherwise, the tools can scaffold migrations for a model that differs from the model used by the application. Don't assume that an optional command-line argument is present; validate arguments and provide a suitable development default or configuration source.

## Args

Expand Down Expand Up @@ -62,6 +64,6 @@ Update-Database -Args '--environment Production'
[2]: xref:core/dbcontext-configuration/index
[3]: /aspnet/core/fundamentals/host/web-host
[4]: /aspnet/core/fundamentals/host/generic-host
[5]: xref:core/dbcontext-configuration/index#constructor-argument
[6]: xref:core/dbcontext-configuration/index#using-dbcontext-with-dependency-injection
[7]: xref:core/dbcontext-configuration/index#onconfiguring
[5]: xref:core/dbcontext-configuration/index
[6]: xref:Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.AddDbContext*
[7]: xref:core/dbcontext-configuration/index#basic-dbcontext-initialization-with-new
9 changes: 7 additions & 2 deletions entity-framework/core/cli/dotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ It's also possible to [put migrations code in a class library separate from the

### Other target frameworks

The CLI tools work with .NET projects and .NET Framework projects. Apps that have the EF Core model in a .NET Standard class library might not have a .NET or .NET Framework project. For example, this is true of Xamarin and Universal Windows Platform apps. In such cases, you can create a .NET console app project whose only purpose is to act as startup project for the tools. The project can be a dummy project with no real code &mdash; it is only needed to provide a target for the tooling.
The CLI tools must execute application code using a .NET runtime. Don't use a platform-specific application, such as .NET MAUI, WinUI, Blazor WebAssembly, or Azure Functions, as the startup project for the tools. Instead, put migrations in a normal cross-platform .NET project with an [`IDesignTimeDbContextFactory<TContext>`](xref:core/cli/dbcontext-creation#from-a-design-time-factory), and use that project as both the target and startup project. See [Using a Separate Migrations Project](xref:core/managing-schemas/migrations/projects#platform-specific-applications).

> [!IMPORTANT]
> Xamarin.Android, Xamarin.iOS, Xamarin.Mac are now integrated directly into .NET (starting with .NET 6) as .NET for Android, .NET for iOS, and .NET for macOS. If you're building with these project types today, they should be upgraded to .NET SDK-style projects for continued support. For more information about upgrading Xamarin projects to .NET, see the [Upgrade from Xamarin to .NET & .NET MAUI](/dotnet/maui/migration) documentation.

Why is a dummy project required? As mentioned earlier, the tools have to execute application code at design time. To do that, they need to use the .NET runtime. When the EF Core model is in a project that targets .NET or .NET Framework, the EF Core tools borrow the runtime from the project. They can't do that if the EF Core model is in a .NET Standard class library. The .NET Standard is not an actual .NET implementation; it's a specification of a set of APIs that .NET implementations must support. Therefore .NET Standard is not sufficient for the EF Core tools to execute application code. The dummy project you create to use as startup project provides a concrete target platform into which the tools can load the .NET Standard class library.
The process running the tools must be able to load the target and startup assemblies. For example, a 64-bit tool process can't load an x86-only startup assembly. Prefer an AnyCPU migrations project. If design-time dependencies require a specific architecture, invoke a matching .NET SDK explicitly. The `--runtime` option controls restore for a runtime identifier; it does not change the architecture of the current tool process.

### ASP.NET Core environment

Expand Down Expand Up @@ -159,6 +159,9 @@ Options:

The [common options](#common-options) are listed above.

> [!WARNING]
> The migration argument specifies the state the database should be in after the command completes. If the database is currently at a newer migration, the command reverts every migration newer than the target by executing its `Down` operations. It doesn't apply one older migration out of order.

The following examples update the database to a specified migration. The first uses the migration name and the second uses the migration ID and a specified connection:

```dotnetcli
Expand Down Expand Up @@ -367,6 +370,8 @@ The [common options](#common-options) are listed above.

Generates a SQL script from migrations.

If `--output` isn't specified, the command writes the script to standard output.

Arguments:

| Argument | Description |
Expand Down
7 changes: 5 additions & 2 deletions entity-framework/core/cli/powershell.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ It's also possible to [put migrations code in a class library separate from the

### Other target frameworks

The Package Manager Console tools work with .NET or .NET Framework projects. Apps that have the EF Core model in a .NET Standard class library might not have a .NET or .NET Framework project. For example, this is true of Xamarin and Universal Windows Platform apps. In such cases, you can create a .NET or .NET Framework console app project whose only purpose is to act as startup project for the tools. The project can be a dummy project with no real code &mdash; it is only needed to provide a target for the tooling.
The Package Manager Console tools must execute application code using a .NET runtime. Don't use a platform-specific application, such as .NET MAUI, WinUI, Blazor WebAssembly, or Azure Functions, as the startup project for the tools. Instead, put migrations in a normal cross-platform .NET project with an [`IDesignTimeDbContextFactory<TContext>`](xref:core/cli/dbcontext-creation#from-a-design-time-factory), and use that project as both the target and startup project. See [Using a Separate Migrations Project](xref:core/managing-schemas/migrations/projects#platform-specific-applications).

> [!IMPORTANT]
> Xamarin.Android, Xamarin.iOS, Xamarin.Mac are now integrated directly into .NET (starting with .NET 6) as .NET for Android, .NET for iOS, and .NET for macOS. If you're building with these project types today, they should be upgraded to .NET SDK-style projects for continued support. For more information about upgrading Xamarin projects to .NET, see the [Upgrade from Xamarin to .NET & .NET MAUI](/dotnet/maui/migration) documentation.

Why is a dummy project required? As mentioned earlier, the tools have to execute application code at design time. To do that, they need to use the .NET or .NET Framework runtime. When the EF Core model is in a project that targets .NET or .NET Framework, the EF Core tools borrow the runtime from the project. They can't do that if the EF Core model is in a .NET Standard class library. The .NET Standard is not an actual .NET implementation; it's a specification of a set of APIs that .NET implementations must support. Therefore .NET Standard is not sufficient for the EF Core tools to execute application code. The dummy project you create to use as startup project provides a concrete target platform into which the tools can load the .NET Standard class library.
Visual Studio and Package Manager Console normally run as 64-bit processes and can't load an x86-only startup assembly. Prefer an AnyCPU migrations project. When all design-time dependencies must be x86, use the .NET CLI with an explicitly selected x86 SDK/tool host.

### ASP.NET Core environment

Expand Down Expand Up @@ -322,6 +322,9 @@ Updates the database to the last migration or to a specified migration.

The [common parameters](#common-parameters) are listed above.

> [!WARNING]
> `-Migration` specifies the state the database should be in after the command completes. If the database is currently at a newer migration, the command reverts every migration newer than the target by executing its `Down` operations. It doesn't apply one older migration out of order.

> [!TIP]
> The `Migration` parameter supports tab-expansion.

Expand Down
Loading
Loading