Skip to content

Commit 6870be0

Browse files
committed
+ class UseCurrentXactIdAsConcurrencyTokenCommandInterceptor to fix cannot retrieve a system column in this context with partitioned table: npgsql/efcore.pg#1035 (comment) @ TbmDbContext.cs
$ mv Db/Entit{ies,y}WithImageId.cs @ c#/shared
1 parent 65c6bc7 commit 6870be0

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

c#/shared/src/Db/TbmDbContext.cs

+34
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,39 @@ private sealed class NoSavePointTransaction(IRelationalConnection connection,
9191
public override bool SupportsSavepoints => false;
9292
}
9393
}
94+
95+
/// <see>https://www.postgresql.org/message-id/flat/141051591267657%40mail.yandex.ru</see>
96+
/// <see>https://dba.stackexchange.com/questions/123145/how-to-view-tuples-changed-in-a-postgresql-transaction/123183#123183</see>
97+
/// <see>https://stackoverflow.com/questions/49214219/what-is-the-meaning-of-epoch-in-txid-current-in-postgresql</see>
98+
/// <see>https://github.com/npgsql/efcore.pg/issues/1035#issuecomment-2118584744</see>
99+
protected class UseCurrentXactIdAsConcurrencyTokenCommandInterceptor : DbCommandInterceptor
100+
{
101+
public static UseCurrentXactIdAsConcurrencyTokenCommandInterceptor Instance => new();
102+
103+
public override InterceptionResult<DbDataReader> ReaderExecuting(
104+
DbCommand command,
105+
CommandEventData eventData,
106+
InterceptionResult<DbDataReader> result)
107+
{
108+
ManipulateCommand(command);
109+
return result;
110+
}
111+
112+
public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
113+
DbCommand command,
114+
CommandEventData eventData,
115+
InterceptionResult<DbDataReader> result,
116+
CancellationToken cancellationToken = default)
117+
{
118+
ManipulateCommand(command);
119+
return new(result);
120+
}
121+
122+
private static void ManipulateCommand(DbCommand command) =>
123+
command.CommandText = command.CommandText.Replace(
124+
"RETURNING xmin",
125+
"RETURNING pg_current_xact_id()::xid");
126+
}
94127
}
95128
public class TbmDbContext<TModelCacheKeyFactory>(ILogger<TbmDbContext<TModelCacheKeyFactory>> logger)
96129
: TbmDbContext(logger)
@@ -113,6 +146,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder options)
113146
options.UseNpgsql(GetNpgsqlDataSource(Config.GetConnectionString("Main")).Value, OnConfiguringNpgsql)
114147
.ReplaceService<IModelCacheKeyFactory, TModelCacheKeyFactory>()
115148
.ReplaceService<IRelationalTransactionFactory, NoSavePointTransactionFactory>()
149+
.AddInterceptors(UseCurrentXactIdAsConcurrencyTokenCommandInterceptor.Instance)
116150
.UseCamelCaseNamingConvention();
117151

118152
var dbSettings = Config.GetSection("DbSettings");

0 commit comments

Comments
 (0)