代码之家  ›  专栏  ›  技术社区  ›  phwt

EF Core with PostgreSQL 16-为GUID创建一个带有“NULLS NOT DISTINCT”的唯一索引

  •  0
  • phwt  · 技术社区  · 10 月前

    我在一个实体中有一处房产,属于以下类型 Guid 它是唯一的,但可以为空。

    由于空GUID等于 00000000-0000-0000-0000-000000000000 ,PostgreSQL不允许我插入Guid为null(全零)的第二条记录,因为它违反了索引约束。

    因此,我已尝试配置 NULLS NOT DISTINCT 通过添加 AreNullsDistinct(false) 指数。

    public class Employee
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public required Guid Id { get; set; }
        public required string FirstName { get; set; }
        public required string LastName { get; set; }
        public Guid AdObjectId { get; set; } // Link employee back to identity in AD, can be null as some employee might not present in the AD
    }
    
    public class DatabaseContext : DbContext
    {
        public DbSet<Employee> Employee { get; set; }
    
        public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Employee>().HasIndex(e => e.AdObjectId).IsUnique().AreNullsDistinct(false);
        }
    }
    

    但是,当我检查DDL时 null不明显 不在索引中:

    create table "Employee"
    (
        "Id"         uuid                           not null
            constraint "PK_Employee" primary key,
        "FirstName"  text                           not null,
        "LastName"   text                           not null,
        "AdObjectId" uuid                           not null
    );
    
    create unique index "IX_Employee_AdObjectId"
        on "Employee" ("AdObjectId");
    

    以下是迁移(仅索引创建部分)供参考:

    migrationBuilder.CreateIndex(
        name: "IX_Employee_AdObjectId",
        table: "Employee",
        column: "AdObjectId",
        unique: true)
        .Annotation("Npgsql:NullsDistinct", false);
    

    我想知道,我是否错过了任何额外的配置 null不明显 出现在指数上?

    环境详细信息 :

    • .NET Core 8
    • PostgreSQL 16
    • Microsoft.EntityFrameworkCore : 8.0.4
    • Microsoft.EntityFrameworkCore.Design : 8.0.4
    • Npgsql.EntityFrameworkCore.PostgreSQL : 8.0.4
    1 回复  |  直到 10 月前
        1
  •  1
  •   sa-es-ir    10 月前

    以下是Npgsql文档:

    默认情况下,当你创建一个唯一索引时,PostgreSQL会将空值视为不同的值;这意味着一个唯一索引可以在一列中包含多个空值。在创建索引时,您还可以指示PostgreSQL将null视为不可区分的;如果列包含多个空值,则会引发唯一的约束冲突。

    似乎你想要的是npgsql的默认行为,你不应该使用 AreNullsDistinct 压制它!

    我建议删除 AreaNulls区分 并创建新的迁移,但在更新数据库之前检查生成的代码。

    npgsql链接: See