Skip to content

Commit b9d5ead

Browse files
committed
Document the SDK breaking change affecting EF tools
1 parent c3e2876 commit b9d5ead

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

entity-framework/core/miscellaneous/internals/tools.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,7 @@ There are two primary inputs to this command: the startup project and the target
2323

2424
It reads information about the projects by injecting an MSBuild .targets file and calling the custom MSBuild target. The .targets file is compiled into dotnet-ef as an embedded resource. The source is located at [src/dotnet-ef/Resources/EntityFrameworkCore.targets](https://github.com/dotnet/efcore/blob/main/src/dotnet-ef/Resources/EntityFrameworkCore.targets).
2525

26-
It has a bit of logic at the beginning to handle multi-targeting projects. Essentially, it just picks the first target framework and re-invokes itself. After a single target framework has been determined, it writes several MSBuild properties like AssemblyName, OutputPath, RootNamespace, etc. to a temporary file that dotnet-ef then reads.
27-
28-
> [!TIP]
29-
> .NET 8 adds a new, streamlined way to read MSBuild properties that will enable us to remove this .targets file. See issue [#32113](https://github.com/dotnet/efcore/issues/32113).
30-
31-
We need to inject this target into both the startup and target project. We do that by leveraging an MSBuild hook created for NuGet and other package managers. That hook automatically loads any file under `$(MSBuildProjectExtensionsPath)` with a name matching the pattern `$(MSBuildProjectName).*.targets`. Unfortunately, we don't know the actual value of the MSBuildProjectExtensionsPath property, and we need it before we can read any MSBuild properties. So, we assume it's set to the default value of `$(MSBuildProjectDirectory)\obj`. If it's not, the user must specify it using the `--msbuildprojectextensionspath` option.
26+
It has a bit of logic at the beginning to handle multi-targeting projects. Essentially, it just picks the first target framework and re-invokes itself. After a single target framework has been determined, it gets several MSBuild properties like AssemblyName, OutputPath, RootNamespace, etc.
3227

3328
After we've collected the project information, we compile the startup project. We assume that the target project will also be compiled transitively.
3429

entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ EF Core 9 targets .NET 8. This means that existing applications that target .NET
2727
|:----------------------------------------------------------------------------------------------------------|------------|
2828
| [Exception is thrown when applying migrations if there are pending model changes](#pending-model-changes) | High |
2929
| [Exception is thrown when applying migrations in an explicit transaction](#migrations-transaction) | High |
30+
| [`Microsoft.EntityFrameworkCore.Design` not found when using EF tools](#tools-design) | Medium |
3031
| [`EF.Functions.Unhex()` now returns `byte[]?`](#unhex) | Low |
3132
| [SqlFunctionExpression's nullability arguments' arity validated](#sqlfunctionexpression-nullability) | Low |
3233
| [`ToString()` method now returns empty string for `null` instances](#nullable-tostring) | Low |
@@ -114,6 +115,48 @@ Otherwise, if your scenario requires an explicit transaction and you have other
114115
options.ConfigureWarnings(w => w.Ignore(RelationalEventId.MigrationsUserTransactionWarning))
115116
```
116117

118+
## Medium-impact changes
119+
120+
<a name="tools-design"></a>
121+
122+
### `Microsoft.EntityFrameworkCore.Design` not found when using EF tools
123+
124+
[Tracking Issue #35265](https://github.com/dotnet/efcore/issues/35265)
125+
126+
#### Old behavior
127+
128+
Previusly, the EF tools required `Microsoft.EntityFrameworkCore.Design` to be referenced in the following way.
129+
130+
```XML
131+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="*.0.0">
132+
<PrivateAssets>all</PrivateAssets>
133+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
134+
</PackageReference>
135+
```
136+
137+
#### New behavior
138+
139+
Starting with .NET SDK 9.0.200 an exception is thrown when an EF tool is invoked:
140+
> :::no-loc text="Could not load file or assembly 'Microsoft.EntityFrameworkCore.Design, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.":::
141+
142+
#### Why
143+
144+
EF tools were relying on an undocumented behavior of .NET SDK that caused private assets to be included in the generated `.deps.json` file. This was fixed in [sdk#45259](https://github.com/dotnet/sdk/pull/45259). Unfortunately, the EF change to account for this doesn't meet the servicing bar for EF 9.0.x, so it will be fixed in EF 10.
145+
146+
#### Mitigations
147+
148+
As a workaround before EF 10 is released you can mark the `Design` assembly reference as publishable:
149+
150+
```XML
151+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1">
152+
<PrivateAssets>all</PrivateAssets>
153+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
154+
<Publish>true</Publish>
155+
</PackageReference>
156+
```
157+
158+
This will include it in the generated `.deps.json` file, but has a side effect of copying `Microsoft.EntityFrameworkCore.Design.dll` to the output and publish folders.
159+
117160
## Low-impact changes
118161

119162
<a name="unhex"></a>

0 commit comments

Comments
 (0)