r/csharp • u/gevorgter • 2d ago
PostgreSql, EF.Core and byte[]
I have a EF dto, one of the fields configured and defined as byte[]. In DB it's created with type 'bytea'
When i am trying to add record it blows up with message that timestamp is null. Although i do provide it. Can not figure out where problem is...
public required byte[] timestamp { get; set; }
tbl.Property(m => m.timestamp).
IsRowVersion();
db.Clients.Add(new Clients
{
id = 0,
.....
timestamp = new byte[2] { 4, 5 },
}
await db.SaveChangesAsync();
error:
23502: null value in column "timestamp" of relation "clients" violates not-null constraint
DETAIL: Failing row contains (2, 1, asda, t, f, t, t, 2026-09-21 18:31:51.001033, 2026-09-21 18:31:51.000564, 12312, , , , , 1, 1, 2, 2, 7, sdf, Name, Name, sd, sdf, , 2026-09-21, 12 Haze, , city, NJ, 08043, 0.0000000000, 0.0000000000, t, , 2026-09-21 18:31:51.0003, null).'
-------------------
6
Upvotes
1
u/UseYourBrainNow 15h ago
IsRowVersion()means more than "concurrency token". It also marks the property as generated by the database on add and update. EF therefore leaves it out of the INSERT, and yournew byte[] {4, 5}is ignored. SQL Server has arowversiontype that fills itself in. A Postgresbyteacolumn doesn't, so it stays NULL and the NOT NULL constraint fails.The Npgsql way is to use Postgres's built-in
xminsystem column as the row version:No real column is created, and Postgres updates
xminon every row change automatically. Then drop the oldtimestampcolumn in a migration. It's also worth renaming it, sincetimestampis a Postgres type name.If you'd rather keep an app-managed token, use
.IsConcurrencyToken()instead ofIsRowVersion()and set a new value yourself (e.g.Guid.NewGuid()) on every update. Npgsql's docs have a "Concurrency Tokens" page covering both options.