如何使用字符串属性作为实体框架中的主键

本文关键字:框架 实体 何使用 字符串 属性 | 更新日期: 2023-09-27 18:16:38

我是EF的新手,尝试在ETF6.0中通过代码优先的方法做我的第一步,现在我有一个问题。

我有一个属性
[Key]
public string FooId { get; set; }

是模型的主键。

但是如果我运行
> - database就下午

在包管理器控制台中使用

命令更新挂起的迁移到数据库,我得到以下错误:

标识列'FooId'的数据类型必须是int, bigint, smallint,Tinyint,或小数或数字,其比例为0,并被限制为nonnullable。

如果我将模型中的PK改为

[Key]
public int FooId { get; set; } 

一切正常

但是我需要PK的类型是字符串,因为它在我的情况下绝对有意义。我知道这样做有缺点,但对我来说是必要的。

我看到一个旧的帖子在这里如何使字符串为主键在实体框架!

但这似乎不能解决我的问题,或者我只是不明白。

我真的不能在SQL数据库上使用字符串作为PK吗?

或者有办法做到这一点吗?

如何使用字符串属性作为实体框架中的主键

这是在没有启用身份自动增量的情况下创建PK的正确方法:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string FooId { get; set; }

如果您需要主键是字符串,那么不要将其作为标识列。标识列将为您生成主键值,如果您打算自己生成这些值,则应关闭该功能。

使用字符串作主键的原因是什么?

我只需将主键设置为一个自动递增的整数字段,并在字符串字段上添加索引。

这样,如果你在表上进行搜索,它们应该相对较快,并且所有的连接和普通查找都不会影响它们的速度。

您还可以控制被索引的字符串字段的数量。换句话说,如果您认为足够的话,您可以说"只索引前5个字符"。或者,如果您的数据可以相对相似,您可以索引整个字段。

对于那些不想更改实体的人来说,另一个可能的答案是告诉DbContext:

  builder.Entity<Food>(b =>
  {
       b.Property(u => u.FooId).HasDefaultValueSql("newsequentialid()");
  });

这将告诉DbContextFood模型有一个名为FoodId的Id,它将需要生成Id。

EF Core默认值:MSDN