Blog Entry

记EFCore迁移时的MSB4057错误

记EFCore迁移时的MSB4057错误

Created
2022/02/21
Updated
2022/02/21

环境

  • VS2022
  • EntityFramework Core 6.0

问题

出现时机

执行: dotnet ef migrations add InitialCreate

错误

E:\xkyii\Code\xkexp\xkexp.cs\EfCore\Hello\Hello.csproj : error MSB4057: 该项目中不存在目标“GetEFProjectMetadata”。
Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.

原因

  • 默认情况下,会在obj目录下生成<ProjctName>.csproj.EntityFrameworkCore.targets文件
  • 由于配置了BaseIntermediateOutputPath,导致临时文件生成到了别处,以致不能正确解析

解决

  • 修改.csproj文件

将原来的

<Project Sdk="Microsoft.NET.Sdk">
<!-- ... -->
</Project>

修改为:

<!-- 1. 本来是这样: <Project Sdk="Microsoft.NET.Sdk"> -->
<Project>
<PropertyGroup>
<!-- 2. 注意: 必须在 imporing Sdk.props 之前 -->
<BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/../build/_Intermediate/</BaseIntermediateOutputPath>
</PropertyGroup>
<!-- 3. 新加 -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<!-- 原来的内容 -->
<!-- ... -->
<!-- 4. 新加 -->
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

如果同时使用了Directory.Build.props,配置了BaseIntermediateOutputPath项之后,将以此项为准,可以考虑和Directory.Build.props配置成一样,避免混淆.

  • 再次执行命令的时候增加--msbuildprojectextensionspath参数,其值与上一步配置的BaseIntermediateOutputPath一致,像这样:
Terminal window
dotnet ef migrations add InitialCreate --msbuildprojectextensionspath ../build/_Intermediate

:::tip 注意

  1. 执行dotnet ef migrations add InitialCreate仍会成功,但是会在项目目录中生成obj目录及.target文件
  2. 参数应是--msbuildprojectextensionspath(全小写),如果使用--MSBuildProjectExtensionsPath(驼峰)会报Unrecognized option '--MSBuildProjectExtensionsPath'(执行仍然会成功,效果相当于没加这参数)
  3. 当前版本是EF Core 6.0,可能其他版本情况会有所不同. :::

参考