问题
我正在尝试设置 Entity Framework Core 8 以使用 PostgreSQL,但无法进行初始迁移。我在本地 Windows 计算机上执行此操作 - 而不是构建服务器。
我可以从 GitHub 下载
EntityFramework.Docs
存储库,并使用 dotnet ef migrations add TestMigration
很好地修改和生成迁移,因此我对安装正确的工具有 99% 的信心。
但是当我尝试在实际解决方案中这样做时,出现以下错误:
错误 MSB4057:项目中不存在目标“GetEFProjectMetadata”。
Microsoft.EntityFrameworkCore.Tools.CommandException:无法检索项目元数据。确保它是一个 SDK 风格的项目。如果您使用自定义 BaseIntermediateOutputPath 或 MSBuildProjectExtensionsPath 值,请使用 --msbuildprojectextensionspath 选项。
在 Microsoft.EntityFrameworkCore.Tools.Project.FromFile(字符串文件,字符串 buildExtensionsDir,字符串框架,字符串配置,字符串运行时)
在 Microsoft.EntityFrameworkCore.Tools.RootCommand.Execute(String[] _)
在 Microsoft.EntityFrameworkCore.Tools.Commands.CommandBase.<>c__DisplayClass0_0.b__0(String[] args)
在 Microsoft.DotNet.Cli.CommandLine.CommandLineApplication.Execute(String[] args)
在 Microsoft.EntityFrameworkCore.Tools.Program.Main(String[] args)无法检索项目元数据。确保它是一个 SDK 风格的项目。如果您使用自定义 BaseIntermediateOutputPath 或 MSBuildProjectExtensionsPath 值,请使用 --msbuildprojectextensionspath 选项。
由于我的公司构建解决方案的方式,我有以下项目:
src/Web/
<- The WebApi host projectsrc/PostgreSQL/
<- The EF Core/PostgreSQL project that implements the IRepository
,并包含 DbContext
。src/PostgreSQL.Host/
<- I can delete this, if not needed.原本我尝试跑步
dotnet ef migrations add InitializeDB --project src/PostgreSQL --startup-project src/Web
我得到了上面的错误。
因此,我添加了 PostgreSQL.Host 项目,这样我就可以尝试不同的方式来初始化
DbContext
- 因为一些帖子指出这可能是问题的原因。
无论我尝试什么,我都会遇到同样的错误。
我尝试过的事情:
IDesignTimeDbContextFactory<MyDbContext>
,无论是否有正常启动流程。Microsoft.EntityFrameworkCore.Tools
之外,还参考.Design
。BaseIntermediateOutputPath
和 MSBuildProjectExtensionsPath
的解决方案 - 没有找到。相关源文件
dotnet ef
回归
Entity Framework Core .NET Command-line Tools 8.0.8
MyDbContext
看起来像这样:
public class MyDbContext : DbContext
{
public MyDbContext (DbContextOptions<MyDbContext > options)
: base(options)
{ }
// ...
}
MyDesignTimeDbContextFactory
看起来像这样:
// This can be removed, if not needed.
public class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContext CreateDbContext(string[] args)
{
// Build configuration
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("../Host.Web/appsettings.json")
.Build();
// Get connection string
var connectionString = configuration.GetSection("PostgreSQLSettings")["ConnectionString"];
// Configure DbContext options
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseNpgsql(connectionString);
return new MyDbContext(optionsBuilder.Options);
}
}
PostgreSQL.csproj
看起来像这样:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>MyProject.PostgreSQL</RootNamespace>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="Ulid" />
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
</Project>
这是
PostgreSQL.Host.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PostgreSQL\PostgreSQL.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
</Project>
命令运行是
的变体dotnet ef migrations add InitializeDB --project src/PostgreSQL --startup-project src/PostgreSQL.Host --verbose
错误:
错误 MSB4057:项目中不存在目标“GetEFProjectMetadata”。
Microsoft.EntityFrameworkCore.Tools.CommandException:无法检索项目元数据。确保它是一个 SDK 风格的项目。如果您使用自定义 BaseIntermediateOutputPath 或 MSBuildProjectExtensionsPath 值,请使用 --msbuildprojectextensionspath 选项。
在 Microsoft.EntityFrameworkCore.Tools.Project.FromFile(字符串文件,字符串 buildExtensionsDir,字符串框架,字符串配置,字符串运行时)
在 Microsoft.EntityFrameworkCore.Tools.RootCommand.Execute(String[] _)
在 Microsoft.EntityFrameworkCore.Tools.Commands.CommandBase.<>c__DisplayClass0_0.b__0(String[] args)
在 Microsoft.DotNet.Cli.CommandLine.CommandLineApplication.Execute(String[] args)
在 Microsoft.EntityFrameworkCore.Tools.Program.Main(String[] args)无法检索项目元数据。确保它是一个 SDK 风格的项目。如果您使用自定义 BaseIntermediateOutputPath 或 MSBuildProjectExtensionsPath 值,请使用 --msbuildprojectextensionspath 选项
对我做错了什么有什么建议吗?
谢谢。
更新
该解决方案有一个 Dicretory.Build.props 文件,其中包括:
<RepoRoot Condition="$(RepoRoot) == ''">$([MSBuild]::EnsureTrailingSlash('$(MSBuildThisFileDirectory)'))</RepoRoot>
<ArtifactsPath>$(RepoRoot)artifacts</ArtifactsPath>
如果我删除
ArtifactsPath
行,那么迁移就会起作用。
我无法删除该行,因为这会破坏解决方案构建过程中的其他内容。
所以,我需要解决该设置。
我尝试手动将 --msbuildprojectextensionspath 设置到该工件文件夹,但它不起作用。
有什么想法吗?
我想出了如何解决这个问题。
创建实体主机/迁移项目 - 其目的只是创建迁移。
在该项目中,添加一个新的
Directory.Build.props
文件,如下所示:
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
This file must exist in the project folder in order to override the solution level Directory.Build.props file.
Otherwise, the changes to the ArtifactsPath breaks the `dotnet ef migrations add` command.
-->
</Project>
现在您可以运行
dotnet ef migrations add
命令。