Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map property to column xmin #382

Closed
wants to merge 1 commit into from
Closed

Conversation

asymetrixs
Copy link

The column "xmin" is a default hidden column for every table in PostgreSQL. In order to use the concurrency feature, the best is to map a property to this auto-updating column. If it is just done as described in the docs now, with a random column name mapped to type 'xid', the column value remains at its default 0 on insert and upate.

The column "xmin" is a default hidden column for every table in PostgreSQL. In order to use the concurrency feature, the best is to map a property to this auto-updating column.
If it is just done as described in the docs now, with a random column name mapped to type 'xid', the column value remains at its default 0 on insert and upate.
@asymetrixs
Copy link
Author

asymetrixs commented Nov 29, 2024

I noticed, that doing this leads to the following error message when using .Distinct() since apparently the DISTINCT operation is not supported on columns of type xid:

      Unhandled exception rendering component: 0A000: could not implement DISTINCT
      
      DETAIL: Some of the datatypes only support hashing, while others only support sorting.
      Npgsql.PostgresException (0x80004005): 0A000: could not implement DISTINCT
      
      DETAIL: Some of the datatypes only support hashing, while others only support sorting.
         at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
         at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
         at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
         at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
         at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
        [...]
        Exception data:
          Severity: ERROR
          SqlState: 0A000
          MessageText: could not implement DISTINCT
          Detail: Some of the datatypes only support hashing, while others only support sorting.
          File: planner.c
          Line: 4787
          Routine: create_distinct_paths

@roji
Copy link
Member

roji commented Nov 30, 2024

@asymetrixs why are you suggesting this change? The docs in their current state already show how to map to xmin, but using the standard EF mechanisms instead of requiring the user to explicitly know about and specify xmin. This is also good for code that needs to run across e.g. both PG and SQL Server.

@roji
Copy link
Member

roji commented Nov 30, 2024

I noticed, that doing this leads to the following error message when using .Distinct() since apparently the DISTINCT operation is not supported on columns of type xid:

Can you open an issue for this with a minimal repro on https://github.com/npgsql/efcore.pg?

@asymetrixs
Copy link
Author

@roji I opened this issue, because either I am doing something wrong or .IsRowVersion() does not work as expected. I pushed an example to https://github.com/asymetrixs/NpgsqlTest
The problem with DISTINCT has not occurred anymore (at least not in the example app), so I'll look into this one again to find out why it is happening in another app.

@roji
Copy link
Member

roji commented Dec 2, 2024

@asymetrixs there's various code in your sample, so I just threw together a minimal console program based on the docs, and it works:

await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();

context.SomeEntities.Add(new());
await context.SaveChangesAsync();

context.ChangeTracker.Clear();

var entity = await context.SomeEntities.SingleAsync();
Console.WriteLine(entity.Version);

public class BlogContext : DbContext
{
    public DbSet<SomeEntity> SomeEntities { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseNpgsql("Host=localhost;Username=test;Password=test")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SomeEntity>()
            .Property(b => b.Version)
            .IsRowVersion();
    }
}

public class SomeEntity
{
    public int Id { get; set; }
    public uint Version { get; set; }
}

Try working with that to understand what the difference is, and if you think there's a problem, please file a bug in https://github.com/npgsql/efcore.pg. In the meantime I'll go ahead and close this issue as the docs are correct, and if there's any bug it should be fixed, rather than updating the docs.

@roji roji closed this Dec 2, 2024
@asymetrixs asymetrixs deleted the patch-1 branch December 2, 2024 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants