SQL Server EF核心defaultValueSql如何通过SELECT设置值

iaqfqrcu  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(119)

我有数据库迁移,其中FormTemplateId-外键,我需要将默认值设置为[dbo].[FormTemplates]中最新记录的Id

migrationBuilder.AddColumn<int>(
                name: "FormTemplateId",
                table: "ContainerMasterTypes",
                type: "int",
                nullable: false,
                defaultValueSql: "SELECT TOP 1 [Id] FROM [dbo].[FormTemplates] ORDER BY [Id] DESC");

并出现错误:Subqueries are not allowed in this context. Only scalar expressions are allowed.'
出什么问题了?我该怎么修正这个错误?

nmpmafwu

nmpmafwu1#

实体框架仅允许您执行SQL Server中已能执行的操作。例如,使用以下表设置:

create table dbo.FormTemplates (
  Id int not null identity(1,1),
  Name nvarchar(50) not null
);
insert dbo.FormTemplates (Name) values (N'Foo'), (N'Bar'), (N'Baz');

create table dbo.ContainerMasterTypes (
  Id int not null identity(1,1),
  Name nvarchar(50) not null
);

尝试修改ContainerMasterTypes表以在默认约束条件中添加具有子查询的新列将失败...

alter table dbo.ContainerMasterTypes
  add FormTemplateId int not null
    constraint DF_ContainerMasterTypes_FormTemplateId
      default (SELECT TOP 1 [Id] FROM [dbo].[FormTemplates] ORDER BY [Id] DESC);

...显示您在.NET中看到的错误消息:
消息1046 15级状态1行3
此上下文中不允许子查询。只允许标量表达式。
若要在SQL Server中执行此操作,您应该将查询 Package 在标量用户定义函数中,并从默认约束引用该函数,即:

create function dbo.LatestFormTemplateId()
returns int as
begin
  return (SELECT TOP 1 [Id] FROM [dbo].[FormTemplates] ORDER BY [Id] DESC)
end
go
alter table dbo.ContainerMasterTypes
  add FormTemplateId int not null
    constraint DF_ContainerMasterTypes_FormTemplateId
      default (dbo.LatestFormTemplateId());

用数据来验证...

insert dbo.ContainerMasterTypes (Name, FormTemplateId) values (N'Something', 1);
insert dbo.ContainerMasterTypes (Name) values (N'Else');

select * from dbo.FormTemplates;
select * from dbo.ContainerMasterTypes;

会产生这样的结果:
| 身份证|姓名|
| - ------|- ------|
| 1个|富|
| 第二章|酒吧|
| 三个|巴兹|
| 身份证|姓名|表单模板ID|
| - ------|- ------|- ------|
| 1个|一些东西|1个|
| 第二章|埃尔塞|三个|
您也需要在EntityFramework中做同样的事情,创建一个 Package 查询的ScalarUDF,然后使用引用UDF的默认约束添加新列。

相关问题