使用一个自动生成的UNIQUEIDENTIFIER,它不是主键的一部分

本文关键字:一部分 UNIQUEIDENTIFIER 自动生成 一个 | 更新日期: 2023-09-27 18:04:36

我有以下EF代码优先实体及其相应的配置:

public class Category
{
    public virtual long Id { get; set; }
    public Guid Guid { get; set; }
    public string Name { get; set; }
}
public class CategoryConfiguration:
    EntityTypeConfiguration<Category>
{
    public CategoryConfiguration ()
    {
        this.HasKey(entity => entity.Id);
        this.Property(entity => entity.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(entity => entity.Guid).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

在字段Guid上设置DatabaseGeneratedOption.Identity选项似乎没有效果,SQL Server中相应的表已禁用IDENTITY选项

是否有一种方法可以在EF中自动生成GUID/UNIQUEIDENTIFIER列,但同时不是主键的一部分?

使用一个自动生成的UNIQUEIDENTIFIER,它不是主键的一部分

EF不会"自动生成"任何与ID相关的东西,这都是由数据库处理的。也DatabaseGeneratedOption。标识与主键无关,它只是EF的一个指示符,表明字段值是由DB生成的,因此应该被拉下。

只要数据库中字段的默认值设置为newid()newsequentialid(),那么DatabaseGeneratedOption.Identity应该可以工作。

a hack…

public calss Guid1 {
    public Guid Guid { get; set; }
}
public class Category {
    public virtual long Id { get; set; }
    public Guid1 Guid { get; set; }
    public string Name { get; set; }
}
public class CategoryConfiguration:EntityTypeConfiguration<Category> {
    public CategoryConfiguration () {
        HasKey(entity => entity.Id);
        Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasReqired(x => x.Guid1);
    }
}
public class Guid1Configuration:EntityTypeConfiguration<Guid1> {
    public Guid1Configuration () {
        HasKey(x => x.Guid);
        Property(x => x.Guid).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

这应该工作,但你会得到一个无用的表Guid1.

为了方便搜索者使用EntityFramworkCore(。. NET核心),您可以执行以下操作:

EF模型(注意创建时的默认值)

public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public Guid BlogGuid { get; set; } = Guid.NewGuid();
        public List<Post> Posts { get; set; }
    }

创建迁移,然后将默认值更改为defaultValueSql: "newid()":

public partial class BlogGuidTest : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<Guid>(
                name: "BlogGuid",
                table: "Blogs",
                nullable: false,
                defaultValueSql: "newid()");
            // Add contraint to be safe
            migrationBuilder.AddUniqueConstraint("BlogGuid_Unique", "Blogs", "BlogGuid");
        }
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropUniqueConstraint("BlogGuid_Unique", "Blogs");
            migrationBuilder.DropColumn(
                name: "BlogGuid",
                table: "Blogs");
        }
    }

然后更新数据库