EF Core迁移设置外键默认值用SELECT报错,如何修复?
问题原因
SQL Server 不允许在列的默认值约束中直接使用子查询(比如你写的SELECT TOP 1 [Id] FROM [dbo].[FormTemplates] ORDER BY [Id] DESC),因为默认值约束要求的是标量表达式——即能直接返回单个值的表达式,子查询属于多语句逻辑,不符合约束的语法规则,因此触发错误提示。
修复方案
提供两种适配不同需求的解决方式:
方式一:用标量值函数封装子查询
如果需要后续新插入记录时,自动使用FormTemplates表的最新Id作为默认值,可以先创建一个标量函数,再将默认值指向该函数:
- 在迁移的
Up方法中添加创建函数的SQL:
migrationBuilder.Sql(@" CREATE FUNCTION dbo.GetLatestFormTemplateId() RETURNS INT AS BEGIN RETURN (SELECT TOP 1 [Id] FROM [dbo].[FormTemplates] ORDER BY [Id] DESC) END ");
- 再添加列并设置默认值:
migrationBuilder.AddColumn<int>( name: "FormTemplateId", table: "ContainerMasterTypes", type: "int", nullable: false, defaultValueSql: "dbo.GetLatestFormTemplateId()");
方式二:迁移时获取当前最新Id作为常量默认值
如果只需要使用执行迁移这一刻的FormTemplates最新Id作为固定默认值,后续表中新增Id不影响默认值,可以直接在迁移代码中查询获取该值,再作为常量设置:
using (var context = new YourDbContext()) { var latestTemplateId = context.FormTemplates .OrderByDescending(t => t.Id) .Select(t => t.Id) .FirstOrDefault(); migrationBuilder.AddColumn<int>( name: "FormTemplateId", table: "ContainerMasterTypes", type: "int", nullable: false, defaultValue: latestTemplateId); }
注意:替换YourDbContext为你实际的DbContext类名,确保迁移执行时能正常连接数据库。
内容的提问来源于stack exchange,提问作者A. Gladkiy
相关产品推荐
相关产品推荐

