【问题标题】:How do you add a Unique case insensitive Index to a PostgresSQL table using EF Fluent API如何使用 EF Fluent API 将不区分大小写的唯一索引添加到 PostgresQL 表
【发布时间】:2022-12-07 22:32:17
【问题描述】:

我最近一直在使用 PostgreSQL 而不是 SQL,因此发现两者之间有很多细微差别。

我希望能够使表中的字符串值唯一,因此使用 EF code first fluent API,我有这段代码。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyTable>()
        .HasIndex(u => u.UniqueValue)
        .IsUnique();
    
    base.OnModelCreating(modelBuilder);
}

创建迁移时,它会生成这个。

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateIndex(
        name: "IX_MyTable_UniqueValue",
        table: "MyTable",
        column: "UniqueValue",
        unique: true);
}

然后,这会将索引添加到 PostgreSQL 表中,并在单词大小写相同时起作用。

例如尝试插入两次“Hello”,但它不起作用。

它确实允许单词的变体,所以我可以插入“Hello”、“HEllo”、“HELlo”等...

看起来可以使用类似的东西在 PostgreSQL 的索引上强制大小写

CREATE UNIQUE INDEX UniqueValue ON MyTable (UPPER(UniqueValue));

但是我不确定如何通过 EF Fluent API 执行此操作并从中创建迁移?

【问题讨论】:

  • 看起来现在你必须设置一个raw SQL migration。支持是stillon the way。您还可以设置一个 generated (computed) column 来执行您的 upper(UniqueValue) 并在其上添加唯一索引。
  • 感谢@Zegarek 提供的信息您不会碰巧拥有用于更改现有索引并添加到​​upper 部分的原始 sql 吗?
  • 您不能以这种方式更改索引,因为它会有效地构建一个新索引,只是重新使用名称。您需要删除您现在拥有的那个,并使用问题中的索引定义来替换它。或者,您可以添加一个单独的 exclusion constraint,效果相同。 Demo
  • 这是很好的信息,谢谢@Zegarek 如果你想将 cmets 重新塑造成一个答案,那么我可以接受。

标签: postgresql entity-framework-core ef-fluent-api


【解决方案1】:

看起来现在你必须设置一个raw SQL migration。尚未添加对 still 的支持 (yet)。您还可以设置一个 generated (computed) column 来保存 upper(UniqueValue) 的结果,然后在其上添加一个唯一索引。

无法添加基于表达式的唯一约束或将表达式添加到现有的唯一索引键。您可以按原样使用您的定义构建新索引:

CREATE UNIQUE INDEX UniqueValue ON MyTable (UPPER(UniqueValue));

或者添加一个 exclusion constraint,它最终做的几乎相同 (as of now, quite far from being supported in EF):

create table test(txt text);
alter table test 
  add constraint case_insensitive_unique 
  exclude using gist(upper(txt) with =);

insert into test(txt) select 'hello';
--INSERT 0 1
insert into test(txt) select 'Hello';
--ERROR:  conflicting key value violates exclusion constraint "case_insensitive_unique"
--DETAIL:  Key (upper(txt))=(HELLO) conflicts with existing key (upper(txt))=(HELLO).

Demo

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 2016-02-17
    • 2012-12-26
    • 2011-12-18
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多