如何配置 EF Core 5 以使 MS SQL Server 数据库生成 Guid 密钥
Posted
技术标签:
【中文标题】如何配置 EF Core 5 以使 MS SQL Server 数据库生成 Guid 密钥【英文标题】:How to configure EF Core 5 to make Guid keys generated by MS SQL Server database 【发布时间】:2021-05-13 04:49:56 【问题描述】:我正在使用带有 SQL Server 的 EF Core 5,并且我有以下简单实体:
public class Person
public Guid Id get; set;
public string Name get; set;
在 DbContext 中添加为:
public DbSet<Person> People get; set;
我运行add-migration Person
得到以下生成的迁移代码:
public partial class Person : Migration
protected override void Up(MigrationBuilder migrationBuilder)
migrationBuilder.CreateTable(
name: "People",
columns: table => new
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true)
,
constraints: table =>
table.PrimaryKey("PK_People", x => x.Id);
);
protected override void Down(MigrationBuilder migrationBuilder)
migrationBuilder.DropTable(
name: "People");
然后我运行update-database
在数据库中创建这个Person
表。
context.People.Add(new Person() Name = "John" );
context.SaveChanges();
查看 EF 日志,我看到执行了 SQL 命令:
Executed DbCommand (21ms) [Parameters=[@p0='115b2a5d-56b7-42c8-2f42-08d8cd03a34e', @p1='John' (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [People] ([Id], [Name])
VALUES (@p0, @p1);
我注意到 Id 的第一个参数是 @p0='115b2a5d-56b7-42c8-2f42-08d8cd03a34e'
,所以这意味着 Guid 是由 EF 生成的,而不是由数据库生成的。我希望它由数据库生成。
所以我在Id
属性中添加了以下属性:
public class Person
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id get; set;
public string Name get; set;
但是当我创建一个新的迁移时,它给了我空的 Up()
和 Down()
方法,这意味着从 EF 的角度来看,数据库中不应有任何更改。为什么是这样?以及如何让 EF Core 5 创建由数据库自动生成的 Id
主键。
【问题讨论】:
迁移可能不会改变,但是日志中生成的SQL会改变吗? Fluent API 选项适合您吗? ***.com/questions/25094711/… 如果你这样做,使用这些属性,从一开始(擦除数据库并重新开始)它是否默认 NewID()? @DavidG 刚刚查看了日志,并没有改变EF生成的SQL,所以参数@p0
还是传给了数据库。
@madoxdev,我刚刚尝试过这样的 Fluent API:“modelBuilder.EntityPerson
我得到SqlException: Cannot insert the value NULL into column 'Id', table 'dbo.People'; column does not allow nulls. UPDATE fails. The statement has been terminated.
我正在阅读 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 行并找到了这个:
Entity Framework Core 不会实施价值生成策略。数据库提供程序在自动生成值的方式上有所不同。有些会为选定的数据类型生成值,例如 Identity、rowversion、GUID。
如果您只想为您的 mssql 数据库生成一个复杂的密钥,那么我建议将 Id 的类型从 guid 更改为字符串
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id get; set;
在迁移文件中是这样的:
migrationBuilder.CreateTable(
columns: table => new
Id = table.Column<string>(type: "nvarchar(450)", nullable: false),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true)
,
【讨论】:
以上是关于如何配置 EF Core 5 以使 MS SQL Server 数据库生成 Guid 密钥的主要内容,如果未能解决你的问题,请参考以下文章
为 ASP.NET Core 5.0 - EF Core 5.0 Web App 配置 PostgreSQL 连接字符串以在 MS 或 Linux 云上运行?