From 6870be03926e40b66c075642d28f0e45d63527f5 Mon Sep 17 00:00:00 2001 From: n0099 Date: Sat, 18 May 2024 11:23:42 +0800 Subject: [PATCH] + class `UseCurrentXactIdAsConcurrencyTokenCommandInterceptor` to fix `cannot retrieve a system column in this context` with partitioned table: https://github.com/npgsql/efcore.pg/issues/1035#issuecomment-2118584744 @ TbmDbContext.cs $ mv Db/Entit{ies,y}WithImageId.cs @ c#/shared --- ...iesWithImageId.cs => EntityWithImageId.cs} | 0 c#/shared/src/Db/TbmDbContext.cs | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+) rename c#/shared/src/Db/{EntitiesWithImageId.cs => EntityWithImageId.cs} (100%) diff --git a/c#/shared/src/Db/EntitiesWithImageId.cs b/c#/shared/src/Db/EntityWithImageId.cs similarity index 100% rename from c#/shared/src/Db/EntitiesWithImageId.cs rename to c#/shared/src/Db/EntityWithImageId.cs diff --git a/c#/shared/src/Db/TbmDbContext.cs b/c#/shared/src/Db/TbmDbContext.cs index 8c8d1b81..3891c38c 100644 --- a/c#/shared/src/Db/TbmDbContext.cs +++ b/c#/shared/src/Db/TbmDbContext.cs @@ -91,6 +91,39 @@ private sealed class NoSavePointTransaction(IRelationalConnection connection, public override bool SupportsSavepoints => false; } } + + /// https://www.postgresql.org/message-id/flat/141051591267657%40mail.yandex.ru + /// https://dba.stackexchange.com/questions/123145/how-to-view-tuples-changed-in-a-postgresql-transaction/123183#123183 + /// https://stackoverflow.com/questions/49214219/what-is-the-meaning-of-epoch-in-txid-current-in-postgresql + /// https://github.com/npgsql/efcore.pg/issues/1035#issuecomment-2118584744 + protected class UseCurrentXactIdAsConcurrencyTokenCommandInterceptor : DbCommandInterceptor + { + public static UseCurrentXactIdAsConcurrencyTokenCommandInterceptor Instance => new(); + + public override InterceptionResult ReaderExecuting( + DbCommand command, + CommandEventData eventData, + InterceptionResult result) + { + ManipulateCommand(command); + return result; + } + + public override ValueTask> ReaderExecutingAsync( + DbCommand command, + CommandEventData eventData, + InterceptionResult result, + CancellationToken cancellationToken = default) + { + ManipulateCommand(command); + return new(result); + } + + private static void ManipulateCommand(DbCommand command) => + command.CommandText = command.CommandText.Replace( + "RETURNING xmin", + "RETURNING pg_current_xact_id()::xid"); + } } public class TbmDbContext(ILogger> logger) : TbmDbContext(logger) @@ -113,6 +146,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder options) options.UseNpgsql(GetNpgsqlDataSource(Config.GetConnectionString("Main")).Value, OnConfiguringNpgsql) .ReplaceService() .ReplaceService() + .AddInterceptors(UseCurrentXactIdAsConcurrencyTokenCommandInterceptor.Instance) .UseCamelCaseNamingConvention(); var dbSettings = Config.GetSection("DbSettings");