可以将迁移存储在包含你的 DbContext项目的不同项目中。 当应用程序项目特定于平台(例如 WinUI、.NET MAUI、Blazor WebAssembly 或 Azure Functions)或面向特定运行时标识符(RID)时,建议这样做。 它还可用于维护多个迁移集。
项目布局
此示例使用三个项目:
| 项目 | 责任 | 参考 |
|---|---|---|
WebApplication1.Data |
DbContext拥有和实体类型 |
EF Core 提供程序 |
WebApplication1.Migrations |
拥有迁移、模型快照和设计时上下文创建 | 数据项目、EF Core 提供程序和 Microsoft.EntityFrameworkCore.Design |
WebApplication1 |
运行应用程序 | 数据项目和迁移项目 |
应用程序在运行时发现或应用迁移时需要引用迁移项目,例如通过调用 Migrate。 如果迁移仅由部署项目应用,并且应用程序永远不会加载它们,则不需要该引用。
配置项目
为迁移创建类库,并添加对包含 <
a0/> 的项目的引用。 将数据库提供程序添加到
Microsoft.EntityFrameworkCore.Design迁移项目。 将设计包标记为专用开发依赖项:<ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="..."> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="..." /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\WebApplication1.Data\WebApplication1.Data.csproj" /> </ItemGroup>在迁移项目中实现
IDesignTimeDbContextFactory<TContext>。 工厂允许工具创建上下文,而无需运行应用程序项目:public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> { public ApplicationDbContext CreateDbContext(string[] args) { var connectionString = args.FirstOrDefault() ?? @"Server=(localdb)\mssqllocaldb;Database=WebApplication1;Trusted_Connection=True"; var options = new DbContextOptionsBuilder<ApplicationDbContext>() .UseSqlServer( connectionString, sqlServer => sqlServer.MigrationsAssembly(typeof(ApplicationDbContextFactory).Assembly.GetName().Name)) .Options; return new ApplicationDbContext(options); } }使设计时提供程序和模型配置与运行时配置保持一致。 该示例接受可选的连接字符串参数,并在未提供任何参数时使用本地开发连接。
在运行时注册上下文时配置迁移程序集:
services.AddDbContext<ApplicationDbContext>( options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"), x => x.MigrationsAssembly("WebApplication1.Migrations")));如果应用程序应用迁移或在运行时发现迁移,请将应用程序的常规引用添加到迁移项目:
<ItemGroup> <ProjectReference Include="..\WebApplication1.Migrations\WebApplication1.Migrations.csproj" /> </ItemGroup>数据项目不得引用迁移项目。 这将创建循环依赖项,因为迁移项目已经引用了数据项目。
如果迁移已存在,请将所有迁移文件和模型快照移动到迁移项目并更新其命名空间。 如果没有现有迁移,设计时工厂允许直接在迁移项目中创建初始迁移。
请使用工具
将迁移项目用作 目标项目和启动项目。 目标项目接收生成的文件,而启动项目由工具生成和执行。 在此布局中,将迁移项目用于这两者都可防止工具执行应用程序启动代码。
从解决方案目录运行以下命令:
dotnet ef migrations add NewMigration \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
相同的项目选项适用于其他命令:
dotnet ef migrations list \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
dotnet ef migrations script --output artifacts/migrations.sql \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
dotnet ef migrations bundle --output artifacts/efbundle \
--project WebApplication1.Migrations \
--startup-project WebApplication1.Migrations
从 EF Core 11 开始,重复的项目选项可以存储在其中 .config/dotnet-ef.json。
在运行命令 --no-build之前或在另一个进程使用其输出之前生成迁移项目。 普通 dotnet ef 命令会自动生成目标和启动项目。
特定于平台的应用程序
不要将特定于平台的应用程序项目用作 EF 工具的启动项目。 移动、浏览器、桌面、函数和 RID 特定的项目可能需要无法执行的工作负荷或本机主机 dotnet ef 。 从 EF Core 11 开始,工具会在使用特定于平台的启动项目时发出警告。
将上述布局用于.NET MAUI、WinUI、Blazor WebAssembly、Azure Functions和类似的应用程序:
- 将上下文和实体类型放入共享数据项目中。
- 将迁移置于
IDesignTimeDbContextFactory<TContext>正常的跨平台.NET项目中。 - 使用迁移项目作为目标和启动项目运行工具。
- 仅当应用程序在运行时加载或应用迁移时,才从应用程序引用迁移项目。
未计划Xamarin和 MAUI 平台项目的直接工具支持;请参阅 dotnet/efcore#7152。 应首先将Xamarin应用程序升级到.NET MAUI。
流程体系结构
运行工具的进程必须能够加载每个设计时程序集。 64 位Visual Studio或.NET进程无法加载仅限 x86 的启动程序集,并且相同的约束适用于 Arm64 和其他体系结构。 首选 AnyCPU 迁移项目。 如果设计时依赖项需要特定的体系结构,请显式调用匹配.NET SDK。
设计时过程体系结构与部署目标不同。 创建捆绑包时,请使用 --target-runtime 或 -TargetRuntime 生成部署 RID 的项目,例如 linux-arm64 或 osx-arm64。