dotnet ef database update中--project参数的作用及必填场景
dotnet ef database update 中--project参数说明 参数核心作用
EF Core命令行工具的两个核心定位参数分工非常明确:
--startup-project(简写-s):指定工具运行时要加载的启动项目,工具会从这个项目里读取应用配置、依赖注入配置、DbContext的运行时配置(包括你写的MigrationAssembly绑定、数据库连接串这些),相当于模拟应用正常启动的环境来加载EF Core相关配置。--project(简写-p):指定工具的默认目标操作项目,所有和迁移文件相关的扫描、文件读写操作,默认都会以这个项目为根目录执行。如果不传这个参数,工具会默认把当前执行命令的工作目录下的项目(如果当前目录有多个项目会直接报错)作为目标项目。
设计这个开关的原因
EF Core的默认约定是「迁移代码文件和DbContext定义放在同一个程序集」,但实际开发中很多团队会出于职责分离、架构分层的需求,把迁移代码单独拆到独立类库(就像你例子里专门建的MigrationProject),甚至一个解决方案里会存在多套迁移、多个DbContext分别存放在不同项目中。
工具不可能自动推断用户当前要操作哪套迁移、要把迁移文件写到哪个项目里,因此必须设计这个显式指定的开关,打破默认约定的限制,支持自定义迁移存储位置的场景。
为什么两个命令的参数要求不一样
你观察到的现象完全符合工具的设计逻辑:
- 执行
dotnet ef migrations add时必须传--project:因为这个命令要生成新的迁移代码文件、更新迁移快照文件,必须明确知道文件要写入哪个项目,你在解决方案根目录执行命令时,目录下有4个项目,工具无法自动判断要把文件写到哪,所以必须显式指定MigrationProject作为目标项目。 - 执行
dotnet ef database update时不传--project也能跑:因为这个命令的核心逻辑是读取已有的迁移文件执行SQL,你已经在StartupProject的DbContext配置里通过MigrationAssembly(typeof(MigrationProject.Empty).Assembly.GetName().Name)明确告诉了EF Core「所有迁移都存放在MigrationProject这个程序集里」,工具加载完启动项目的配置后,会直接去指定的程序集里扫描所有迁移类,不需要靠--project参数定位迁移位置,自然可以正常执行。
必须指定--project参数的场景
以下场景执行database update时不能省略该参数:
- 你没有在DbContext配置中显式指定
MigrationAssembly,仍然使用默认的「迁移与DbContext同程序集」约定,且当前执行命令的工作目录不是DbContext所在的项目目录。此时工具会默认在当前目录的项目里扫描迁移,找不到对应迁移类就会报错,必须用--project指向DbContext所在项目。 - 解决方案中存在多套独立迁移、多个DbContext,且启动项目中没有为每个DbContext显式绑定对应的迁移程序集。此时工具无法判断你要执行哪个项目下的迁移,必须通过
--project指定对应迁移项目,通常还要配合--context参数指定目标DbContext。 - 使用EF Core 3.1及更早的旧版本时,工具对
MigrationAssembly配置的读取逻辑不完善,哪怕你在启动项目里配了迁移程序集,工具也可能无法自动定位,必须显式传--project指向迁移项目才能正常扫描到迁移。 - 没有独立的启动项目,直接以类库项目作为工具运行入口时(即
--startup-project和目标项目为同一个类库),如果迁移文件不在当前工作目录对应的项目下,必须通过--project指定迁移所在项目。
一个简单的判断规则:所有需要对迁移文件做写操作的命令(新增迁移、删除迁移、生成迁移脚本到本地文件),只要迁移文件不在当前工作目录的默认项目下,必须传
--project指定写入位置;仅读取已有迁移执行更新的命令,如果已经在运行时配置中明确了迁移程序集位置,可以不传该参数。
内容的提问来源于stack exchange,提问作者Display Name
相关产品推荐
相关产品推荐

