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),