Table of Contents

Npgsql 9.0 Release Notes

Npgsql.EntityFrameworkCore.PostgreSQL version 9.0 is out and available on nuget.org.

Note

We're considering to start dropping support for synchronous APIs (NpgsqlConnection.Open, NpgsqlCommand.ExecuteNonQuery, etc.) starting with Npgsql 10.0. The current plan is to deprecate the API by throwing a runtime exception by default (with a switch to re-enable synchronous I/O) for Npgsql 10.0, while possibly completely removing it for Npgsql 11.0. This is in line with ASP.NET Core and .NET runtime in general, which are moving in the direction of async I/O only (for example, System.IO.Pipelines doesn't have synchronous I/O). If you have any questions or want to share you experience/issues with async I/O, please feel free to post in the issue.

Tracing improvements

Several quality-of-life improvements have been implemented for Npgsql's OpenTelemetry tracing support. You can now do the following via the new NpgsqlDataSourceBuilder.ConfigureTracingOptions API:

  • Specify a filter which determines which commands get traced
  • Set the the tracing span name (e.g. use the command's SQL as the span name)
  • Add arbitrary tags to the tracing span, based on the command
  • Disable the time-to-first-read event that's emitted in spans

See the tracing documentation for more information.

Mapping improvements

Support System.Text.Json polymorphism with PostgreSQL jsonb

Note

If you're using EF Core, the below pertains to the EF provider's legacy POCO mapping, and not to the recommended ToJson mapping. Unfortunately, the latter does not yet support polymorphic serialization (support for this may be added in EF 10).

System.Text.Json has supported polymorphic serialization for a while, using a JSON $type property as the type discriminator. However, it was required that the $type property be at the top of the JSON document; this causes problems serializing to the PostgreSQL jsonb type, since that type does not preserve property order in JSON objects.

System.Text.Json 9.0 brings support for out-of-order metadata reads, which is an opt-in feature allowing the $type property to be anywhere in the JSON object. When using Npgsql, you can opt into this when configuring your NpgsqlDataSourceBuilder as follows:

var builder = new NpgsqlDataSourceBuilder("<connection string>");
builder
    .EnableDynamicJson()
    .ConfigureJsonOptions(new JsonSerializerOptions { AllowOutOfOrderMetadataProperties = true });
await using var dataSource = builder.Build();

Once that's done, you can use JSON polymorphism with jsonb. If you're still targeting .NET 8.0, you can take a reference on System.Text.Json 9.0 in order to use AllowOutOfOrderMetadataProperties.

Add support for cidr <-> IPNetwork mapping

.NET 8 added a new type IPNetwork which represents an IP network with an IPAddress containing the network prefix and an int defining the prefix length. This type seems to be a perfect fit for PostgreSQL's cidr type, which is why we added support to read and write it. The default when reading a cidr is still NpgsqlCidr in 9.0, though this will likely change in Npgsql 10.0. See this issue for more info.

Add support for interval's infinity values via NodaTime's Period.MinValue/Period.MaxValue

PostgreSQL 17 added support for infinity values with interval type. In turn, Npgsql 9.0 adds native support to read and write them via NodaTime's Period.MinValue and Period.MaxValue. Note that while using this feature with previous versions of PostgreSQL, instead of infinity values you'll get the minimum and maximum values for interval type due to the way infinity values are implemented by PostgreSQL. See this issue for more info.

Replication improvements

  • Parallel in-progress transactions with logical streaming replication protocol V4 allow clients to handle multiple in-progress transactions in parallel instead of sequentially. See this issue for more info.
  • ReplicationValue.GetFieldName() ReplicationValue.GetFieldName allows clients to receive the name of changed column while reading rows from replication stream. See this issue for more info.

Breaking changes

.NET Standard 2.0 (and .NET Framework) is not supported

Npgsql 9.0 drops support for .NET Standard 2.0, and in turn .NET Framework. Npgsql is a constantly evolving driver, which makes it problematic to add new features which use APIs that do not exist on older versions of .NET. This doesn't mean you can't use Npgsql with .NET Standard 2.0: we're still committed to supporting Npgsql 8.0 (which does support .NET Standard 2.0). See this issue for more info.

Change some PgOutputReplicationOptions properties to support logical streaming replication protocol V4

The main changes are in the PgOutputReplicationOptions class, where ProtocolVersion and StreamingMode properties were changed to an enum. See this issue for more info.

With the new UseSslClientAuthenticationOptionsCallback callback, users have much more control over the way Npgsql connects to PostgreSQL via SslStream. This makes other callbacks, like UseUserCertificateValidationCallback and UseClientCertificate less useful, which is why we're obsoleting them. See this issue for more info.

The default value of ConnectionLifetime property in connection string is set to 1 hour

Previously, the default value of this property was set to 0, which made connections last indefinitely. The old behavior was problematic because each physical connection on PostgreSQL's side holds on certain caches, which can only grow over time. See this pull request for more info.