Skip to content

Commit

Permalink
Add documentation for MSBuild integration
Browse files Browse the repository at this point in the history
Clean up connection string documentation
  • Loading branch information
AndriySvyryd committed Nov 12, 2024
1 parent 84be865 commit b4e96a2
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 102 deletions.
11 changes: 9 additions & 2 deletions entity-framework/core/cli/dotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: EF Core tools reference (.NET CLI) - EF Core
description: Reference guide for the Entity Framework Core .NET Core CLI tools
author: SamMonoRT
ms.date: 11/15/2021
ms.date: 11/08/2024
uid: core/cli/dotnet
---

Expand Down Expand Up @@ -173,7 +173,7 @@ The [common options](#common-options) are listed above.

## `dotnet ef dbcontext optimize`

Generates a compiled version of the model used by the `DbContext`.
Generates a compiled version of the model used by the `DbContext` and precompiles queries.

See [Compiled models](xref:core/performance/advanced-performance-topics#compiled-models) for more information.

Expand All @@ -183,6 +183,13 @@ Options:
|:-----------------------------------------|:------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <nobr>`--output-dir <PATH>`</nobr> | `-o` | The directory to put files in. Paths are relative to the project directory. |
| <nobr>`--namespace <NAMESPACE>`</nobr> | `-n` | The namespace to use for all generated classes. Defaults to generated from the root namespace and the output directory plus `CompiledModels`. |
| <nobr>`--suffix <SUFFIX>`</nobr> | | The suffix to attach to the name of all the generated files. E.g. `.g` could be used to indicate that these files contain generated code |
| <nobr>`--no-scaffold`</nobr> | | Don't generate a compiled model. This is used when the compiled model has already been generated. |
| <nobr>`--precompile-queries`</nobr> | | Generate precompiled queries. This is required for NativeAOT compilation if the target project contains any queries |
| <nobr>`--nativeaot`</nobr> | | Generate additional code in the compiled model required for NativeAOT compilation and precompiled queries |

> [!NOTE]
> NativeAOT support and precompiled queries are considered experimental in EF 9 and could change dramatically in the next release.
The [common options](#common-options) are listed above.

Expand Down
49 changes: 49 additions & 0 deletions entity-framework/core/cli/msbuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: EF Core MSBuild tasks - EF Core
description: Reference guide for the Entity Framework Core .NET MSBuild tasks
author: ansvyryd
ms.date: 11/08/2024
uid: core/cli/msbuild
---

# Entity Framework Core MSBuild integration

Starting with EF 9, you can use an MSBuild task to generate the compiled model and precompiled queries automatically either when the project is built or when it's published. This is mainly intended to be used with NativeAOT publishing.

> [!WARNING]
> NativeAOT support and the MSBuild integration are experimental features, and are not yet suited for production use.
## Installing the tasks

To get started, install the [Microsoft.EntityFrameworkCore.Tasks](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Tasks/) NuGet package. For example:

```dotnetcli
dotnet add package Microsoft.EntityFrameworkCore.Tasks
```

> [!NOTE]
> **Every** project that needs to be compiled with generated files should reference the NuGet package, it is not transitive by default.
## Using the tasks

If the project specifies `<PublishAot>true</PublishAot>` then by default the MSBuild task will generate a compiled model and precompiled queries during publishing. Otherwise, you can set the following properties to control the generation behavior:

| MSBuild property | Description |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| EFOptimizeContext | Set to `true` to enable MSBuild integration. |
| EFScaffoldModelStage | Set to `publish`, `build` or `none` to indicate at which stage the compiled model will be generated. Defaults to `publish`. |
| EFPrecompileQueriesStage | Set to `publish`, `build` or `none` to indicate at which stage the precompiled queries will be generated. Defaults to `publish`. |
| DbContextName | The derived `DbContext` class to use. Class name only or fully qualified with namespaces. If this option is omitted, EF Core will perform generation for all context classes in the project. |
| EFTargetNamespace | The namespace to use for all generated classes. If this option is omitted, EF Core will use `$(RootNamespace)`. |
| EFOutputDir | The folder to put the generated files before the project is compiled. If this option is omitted, EF Core will use `$(IntermediateOutputPath)`. |
| EFNullable | Whether nullable reference types will be used in the generated code. If this option is omitted, EF Core will use `$(Nullable)`. |

## Limitations

* A different startup project cannot be specified when using this approach as it would introduce an inverse build dependency. This means that the context project needs to be autosuficient in terms of configuration, so if your app normally configures the context using a host builder in a different project you'd need to [implement _IDesignTimeDbContextFactory&lt;TContext&gt;_](xref:core/cli/dbcontext-creation#from-a-design-time-factory) in the context project.
* Since the project needs to be compilable before the compiled model is generated this approach doesn't support partial method implementations for customization of the compiled model.
* Currently, this will always generate additional code in the compiled model that's required for NativeAOT. If you are not planning to enable NativeAOT then [generate the compiled model using the CLI tools](xref:core/cli/dotnet#optimize).

## Additional resources

* [Compiled models](xref:core/performance/advanced-performance-topics#compiled-models)
7 changes: 5 additions & 2 deletions entity-framework/core/cli/powershell.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: EF Core tools reference (Package Manager Console) - EF Core
description: Reference guide for the Entity Framework Core Visual Studio Package Manager Console
author: SamMonoRT
ms.date: 11/15/2021
ms.date: 11/08/2024
uid: core/cli/powershell
---
# Entity Framework Core tools reference - Package Manager Console in Visual Studio
Expand Down Expand Up @@ -185,6 +185,9 @@ Parameters:

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

> [!NOTE]
> The PMC tools currently don't support generating code required for NativeAOT compilation and precompiled queries.
The following example uses the defaults and works if there is only one `DbContext` in the project:

```powershell
Expand Down Expand Up @@ -246,7 +249,7 @@ Example that scaffolds only selected tables and creates the context in a separat
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables "Blog","Post" -ContextDir Context -Context BlogContext -ContextNamespace New.Namespace
```

The following example reads the connection string from the project's configuration possibly set using the [Secret Manager tool](/aspnet/core/security/app-secrets#secret-manager).
The following example [reads the connection string using Configuration](xref:core/miscellaneous/connection-strings#aspnet-core).

```powershell
Scaffold-DbContext "Name=ConnectionStrings:Blogging" Microsoft.EntityFrameworkCore.SqlServer
Expand Down
4 changes: 2 additions & 2 deletions entity-framework/core/dbcontext-configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ ASP.NET Core applications are [configured using dependency injection](/aspnet/co
services.AddControllers();
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
options => options.UseSqlServer("name=DefaultConnection"));
}
-->

[!code-csharp[snippet_1](../../../samples/core/Miscellaneous/ConfiguringDbContext/WebApp9/Program9.cs?name=snippet_1)]

The preceding code registers `ApplicationDbContext`, a subclass of `DbContext`, as a scoped service in the ASP.NET Core app service provider. The service provider is also known as the dependency injection container. The context is configured to use the SQL Server database provider and reads the connection string from ASP.NET Core configuration.
The preceding code registers `ApplicationDbContext`, a subclass of `DbContext`, as a scoped service in the ASP.NET Core app service provider. The service provider is also known as the dependency injection container. The context is configured to use the SQL Server database provider and reads the connection string from [ASP.NET Core configuration](xref:core/miscellaneous/connection-strings#aspnet-core).

The `ApplicationDbContext` class must expose a public constructor with a `DbContextOptions<ApplicationDbContext>` parameter. This is how context configuration from `AddDbContext` is passed to the `DbContext`. For example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Applying Migrations - EF Core
description: Strategies for applying schema migrations to production and development databases using Entity Framework Core
author: SamMonoRT
ms.date: 11/02/2021
ms.date: 10/29/2024
uid: core/managing-schemas/migrations/applying
---
# Applying Migrations
Expand Down Expand Up @@ -117,9 +117,6 @@ The EF command-line tools can be used to apply migrations to a database. While p
* The SQL commands are applied directly by the tool, without giving the developer a chance to inspect or modify them. This can be dangerous in a production environment.
* The .NET SDK and the EF tool must be installed on production servers and requires the project's source code.

> [!NOTE]
> Each migration is applied in its own transaction. See [GitHub issue #22616](https://github.com/dotnet/efcore/issues/22616) for a discussion of possible future enhancements in this area.
### [.NET Core CLI](#tab/dotnet-core-cli)

The following updates your database to the latest migration:
Expand Down
65 changes: 2 additions & 63 deletions entity-framework/core/managing-schemas/scaffolding/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,69 +47,8 @@ dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog
Scaffold-DbContext 'Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook' Microsoft.EntityFrameworkCore.SqlServer
```

***

#### User secrets for connection strings

If you have a .NET application that uses the hosting model and configuration system, such as an ASP.NET Core project, then you can use the `Name=<connection-string>` syntax to read the connection string from configuration.

For example, consider an ASP.NET Core application with the following configuration file:

```json
{
"ConnectionStrings": {
"Chinook": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Chinook"
}
}
```

This connection string in the config file can be used to scaffold from a database using:

#### [.NET Core CLI](#tab/dotnet-core-cli)

```dotnetcli
dotnet ef dbcontext scaffold "Name=ConnectionStrings:Chinook" Microsoft.EntityFrameworkCore.SqlServer
```

#### [Visual Studio PMC](#tab/vs)

```powershell
Scaffold-DbContext 'Name=ConnectionStrings:Chinook' Microsoft.EntityFrameworkCore.SqlServer
```

***

However, storing connection strings in configuration files is not a good idea, since it is too easy to accidentally expose them, for example, by pushing to source control. Instead, connection strings should be stored in a secure way, such as using [Azure Key Vault](/azure/key-vault/keys/quick-create-net) or, when working locally, the [Secret Manager tool](/aspnet/core/security/app-secrets#secret-manager), aka "User Secrets".

For example, to use the User Secrets, first remove the connection string from your ASP.NET Core configuration file. Next, initialize User Secrets by executing the following command in the same directory as the ASP.NET Core project:

```dotnetcli
dotnet user-secrets init
```

This command sets up storage on your computer separate from your source code and adds a key for this storage to the project.

Next, store the connection string in user secrets. For example:

```dotnetcli
dotnet user-secrets set ConnectionStrings:Chinook "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook"
```

Now the same command that previous used the named connection string from the config file will instead use the connection string stored in User Secrets. For example:

#### [.NET Core CLI](#tab/dotnet-core-cli)

```dotnetcli
dotnet ef dbcontext scaffold "Name=ConnectionStrings:Chinook" Microsoft.EntityFrameworkCore.SqlServer
```

#### [Visual Studio PMC](#tab/vs)

```powershell
Scaffold-DbContext 'Name=ConnectionStrings:Chinook' Microsoft.EntityFrameworkCore.SqlServer
```

***
> [!TIP]
> You can [use Configuration to store and retrieve the connection string](xref:core/miscellaneous/connection-strings#aspnet-core)
#### Connection strings in the scaffolded code

Expand Down
15 changes: 15 additions & 0 deletions entity-framework/core/miscellaneous/connection-strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The ASP.NET Core configuration can store connection strings with various provide

* In the `appsettings.Development.json` or `appsettings.json` file.
* In an environment variable
* Using [Azure Key Vault](/azure/key-vault/keys/quick-create-net)
* Using the [Secret Manager tool](/aspnet/core/security/app-secrets#secret-manager)

> [!WARNING]
Expand All @@ -30,10 +31,24 @@ For example, the [Secret Manager tool](/aspnet/core/security/app-secrets#secret-
See the [Configuration section of the ASP.NET Core documentation](/aspnet/core/fundamentals/configuration) for more information.

```dotnetcli
dotnet user-secrets init
dotnet user-secrets set ConnectionStrings:YourDatabaseAlias "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=YourDatabase"
```

Then, in scaffolding, use a connection string that consists of `Name=<database-alias>`.

#### [.NET Core CLI](#tab/dotnet-core-cli)

Check failure on line 40 in entity-framework/core/miscellaneous/connection-strings.md

View workflow job for this annotation

GitHub Actions / lint

Heading levels should only increment by one level at a time [Expected: h3; Actual: h4]

Check failure on line 40 in entity-framework/core/miscellaneous/connection-strings.md

View workflow job for this annotation

GitHub Actions / lint

Heading levels should only increment by one level at a time [Expected: h3; Actual: h4]

```dotnetcli
dotnet ef dbcontext scaffold Name=ConnectionStrings:YourDatabaseAlias Microsoft.EntityFrameworkCore.SqlServer
```

#### [Visual Studio PMC](#tab/vs)

```powershell
Scaffold-DbContext 'Name=ConnectionStrings:YourDatabaseAlias' Microsoft.EntityFrameworkCore.SqlServer
```

[!INCLUDE [managed-identities-test-non-production](~/core/includes/managed-identities-test-non-production.md)]

The following example shows the connection string stored in `appsettings.json`.
Expand Down
32 changes: 7 additions & 25 deletions entity-framework/core/what-is-new/ef-core-9.0/whatsnew.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: What's New in EF Core 9
description: Overview of new features in EF Core 9
author: ajcvickers
ms.date: 10/10/2024
ms.date: 10/21/2024
uid: core/what-is-new/ef-core-9.0/whatsnew
---

Expand Down Expand Up @@ -1151,38 +1151,21 @@ Notice that the model was not built when starting the application because the co
### MSBuild integration
With the above approach, the compiled model still needs to be regenerated manually when the entity types or `DbContext` configuration is changed. However, EF9 ships with MSBuild and targets package that can automatically update the compiled model when the model project is built! To get started, install the [Microsoft.EntityFrameworkCore.Tasks](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Tasks/) NuGet package. For example:
With the above approach, the compiled model still needs to be regenerated manually when the entity types or `DbContext` configuration is changed. However, EF9 ships with an MSBuild task package that can automatically update the compiled model when the model project is built! To get started, install the [Microsoft.EntityFrameworkCore.Tasks](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Tasks/) NuGet package. For example:
```dotnetcli
dotnet add package Microsoft.EntityFrameworkCore.Tasks --version 9.0.0-preview.4.24205.3
dotnet add package Microsoft.EntityFrameworkCore.Tasks --version 9.0.0
```
> [!TIP]
> Use the package version in the command above that matches the version of EF Core that you are using.
Then enable the integration by setting the `EFOptimizeContext` property to your `.csproj` file. For example:
Then enable the integration by setting the `EFOptimizeContext` and `EFScaffoldModelStage` properties in your `.csproj` file. For example:
```xml
<PropertyGroup>
<EFOptimizeContext>true</EFOptimizeContext>
</PropertyGroup>
```
There are additional, optional, MSBuild properties for controlling how the model is built, equivalent to the options passed on the command line to `dotnet ef dbcontext optimize`. These include:
| MSBuild property | Description |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| EFOptimizeContext | Set to `true` to enable auto-compiled models. |
| DbContextName | The DbContext class to use. Class name only or fully qualified with namespaces. If this option is omitted, EF Core will find the context class. If there are multiple context classes, this option is required. |
| EFStartupProject | Relative path to the startup project. Default value is the current folder. |
| EFTargetNamespace | The namespace to use for all generated classes. Defaults to generated from the root namespace and the output directory plus CompiledModels. |
In our example, we need to specify the startup project:
```xml
<PropertyGroup>
<EFOptimizeContext>true</EFOptimizeContext>
<EFStartupProject>..\App\App.csproj</EFStartupProject>
<EFScaffoldModelStage>build</EFScaffoldModelStage>
</PropertyGroup>
```
Expand All @@ -1196,7 +1179,7 @@ dotnet exec --depsfile D:\code\EntityFramework.Docs\samples\core\Miscellaneous\N
--runtimeconfig D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\App\bin\Release\net8.0\App.runtimeconfig.json G:\packages\microsoft.entityframeworkcore.tasks\9.0.0-preview.4.24205.3\tasks\net8.0\..\..\tools\netcoreapp2.0\ef.dll dbcontext optimize --output-dir D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\Model\obj\Release\net8.0\
--namespace NewInEfCore9
--suffix .g
--assembly D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\Model\bin\Release\net8.0\Model.dll --startup-assembly D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\App\bin\Release\net8.0\App.dll
--assembly D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\Model\bin\Release\net8.0\Model.dll
--project-dir D:\code\EntityFramework.Docs\samples\core\Miscellaneous\NewInEFCore9.CompiledModels\Model
--root-namespace NewInEfCore9
--language C#
Expand All @@ -1216,8 +1199,7 @@ Model loaded with 2 entity types.
Now, whenever the model changes, the compiled model will be automatically rebuilt as soon as the project is built.
> [!NOTE]
> We are working through some performance issues with changes made to the compiled model in EF8 and EF9. See [Issue 33483#](https://github.com/dotnet/efcore/issues/33483) for more information.
For more information see [MSBuild integration](xref:core/cli/msbuild).
<a name="read-only-primitives"></a>
Expand Down
Loading

0 comments on commit b4e96a2

Please sign in to comment.