Skip to content

BulkInsertOrUpdateAsync always tries to create unique index for Postgresql #1956

Description

@kick2nick

Summary

UpsertAsync always tries to create a unique constraint even if it already exists in the target table.

Version

  • EFCore.BulkExtensions 10.0.1
  • EFCore.BulkExtensions.PostgreSql 10.0.1
  • Npgsql.EntityFrameworkCore.PostgreSQL 10.0.1
  • .NET 10 / PostgreSQL 17

Reproduce

class Example
{
  public int Id { get; set; }
  
  public int OtherUniqueKey { get; set; }
}

var config = new BulkConfig { UpdateByProperties = new List<string> { nameof(Example.OtherUniqueKey) } };
await using var dbTransaction = await dbContext.Database.BeginTransactionAsync();
await dbContext.BulkInsertOrUpdateAsync(batch, config); 

Fails with the error:
CREATE INDEX CONCURRENTLY cannot run inside a transaction block
because it tries to create a unique index inside the transaction on the OtherUniqueKey column, even though it already exists.

Root cause

In EFCore.BulkExtensions.PostgreSql/SqlAdapters/PostgreSql/PostgreSqlAdapter.cs, the ReconfigureTableInfo method has a signature with DbContext in its parameters:

public string? ReconfigureTableInfo(DbContext context, TableInfo tableInfo)

However, in the implemented interface, the parameter was changed to:

virtual string? ReconfigureTableInfo(BulkContext context, TableInfo tableInfo) { return null; }

Because of this type mismatch, the method in PostgreSqlAdapter does not override the interface method. As a result, the schema for the index search is not set, and the index is not found.

Expected behavior

The schema is set correctly inside TableInfo, the index is found, and there is no attempt to create a duplicate unique index.

Suggested fix

Replace DbContext with BulkContext in the ReconfigureTableInfo method signature inside EFCore.BulkExtensions.PostgreSql/SqlAdapters/PostgreSql/PostgreSqlAdapter.cs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions