Entity framework core 对Guid类型主键上的[DatabaseGenerated(DatabaseGenerateOptions.Identity)]的实体框架7数据批注支持
我有一个实体基类,用于所有实体的基础:Entity framework core 对Guid类型主键上的[DatabaseGenerated(DatabaseGenerateOptions.Identity)]的实体框架7数据批注支持,entity-framework-core,Entity Framework Core,我有一个实体基类,用于所有实体的基础: public abstract class EntityBase : IEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get { return _id; } set {
public abstract class EntityBase : IEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id
{
get
{
return _id;
}
set
{
if (_id.Equals(default(Guid)))
_id = value;
if (_id.Equals(value))
return;
throw new InvalidOperationException("Primary Keys cannot be changed.");
}
}
Guid _id = default(Guid);
[Timestamp]
public byte[] RowVersion { get; set; }
}
但是,[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
没有任何效果
已在CreateTable方法中创建的迁移如下所示:
columns: table => new
{
Id = table.Column<Guid>(nullable: false),...
是[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
实体框架7不再支持?还是我遗漏了什么?[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
在EF7中受支持
由于EF7针对不同的数据库提供程序,它在迁移中的存储方式发生了变化。由于并非所有提供程序都支持标识列,因此没有identity
参数。相反,它存储为特定于提供程序的注释。因此,当一列要用作SQL Server特定的IDENTITY
列时,您将看到以下语法
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Id=table.Column(可空:false)
.Annotation(“SqlServer:ValueGenerationStrategy”,SqlServerValueGenerationStrategy.IdentityColumn),
DatabaseGeneratedOption.Identity
的语义与以前相同。当添加新行时,数据库将生成一个值。以SQL Server为目标时,如果在任何integer type属性上指定了它,则EF7将为其创建标识列。由于IDENTITY
不能在非整数或非数字类型上指定,因此对于任何其他类型,都不会有任何此类注释。尽管该属性仍然具有添加新行将生成值的功能
在您的示例中,属性为
Guid
类型,在SQL Server中转换为uniqueidentifier
类型。无法设置此类型IDENTITY
,因此在生成的迁移中找不到注释。若您尝试在不指定值的情况下添加记录,数据库将为您生成一个值。如果显式地将值设置为属性Id
EF7将使用该值并将其传播到数据库。这是注释的预期效果。与EF6相比,这是一个稍微令人失望的变化。现在是否需要迁移将ID列上的“默认值或绑定”属性设置为(newsequentialid())-EF6过去的方式?@John-对于启用值生成的Guid类型的属性,EF7使用与newsequentialid()
相同的算法在客户端生成新值。因此,即使未设置属性默认值或绑定
,行为也应保持不变。如果您想强制服务器生成值,而不是在客户端生成值,您可以在OnModelCreating
方法中使用以下代码:modelBuilder.Entity().Property(e=>e.Id).HasDefaultValueSql(“newsequentialid()”
这将把服务器上的默认值或绑定
属性设置为newsequentialid()
。很酷,谢谢。我已经测试过这个方法。但是,尽管DB没有生成密钥,但我遇到了一个问题,即在向DB添加实体时,主键由数据库设置,但EF随后尝试使用自己生成的密钥更改该密钥。导致实体库抛出无效操作异常,如上面的代码所示。现在我又回到了EF6,在认真使用EF7之前,我会多玩一点。
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),