Table of Contents

7.0 Release Notes

New features

ExecuteUpdate and ExecuteDelete

Support has been added for the new EF Core 7.0 ExecuteUpdate and ExecuteDelete, which allow expressing arbitrary, efficient updates via LINQ. See the EF What's new section for documentation.

Support for DbDataSource

Npgsql 7.0 introduced NpgsqlDataSource, a major improvement to how database connections and configuration are managed in System.Data. NpgsqlDataSource enabled rich new configuration APIs, which are also available when using the Npgsql EF provider:

// Create a data source with the configuration you want:
var dataSourceBuilder = new NpgsqlDataSourceBuilder(builder.Configuration.GetConnectionString("MyContext"));
dataSourceBuilder
    .UseLoggerFactory(loggerFactory) // Configure ADO.NET logging
    .UsePeriodicPasswordProvider(); // Automatically rotate the password periodically
await using var dataSource = dataSourceBuilder.Build();

// Pass your data source to the EF provider:
builder.Services.AddDbContext<MyContext>(options => options.UseNpgsql(dataSource);

Note that the data source configuration works at the Npgsql ADO.NET layer, and is distinct from EF-level configuration. More improvements are planned in 8.0, to make data source usage more streamlined, especially around type mapping plugins, enums, etc.

Extensive support for aggregate function translation

EF Core 7.0 added support for translating provider-specific aggregate functions, and EFCore.PG builds on top of that to translate most major aggregate functions that PostgreSQL supports. This unlocks support for:

  • string_agg: pack a column's values into a single string, with or without a delimiter.
  • array_agg: pack a column's values into a PostgreSQL array. This can help with efficient fetching of dependent values, avoiding the so-called "cartesian explosion" problem.
  • Statistical functions: standard deviation, variance and many others.
  • Spatial functions: ST_Union, ST_Collect, ST_Extent and ST_ConvexHull.
  • JSON functions: load values from the database as JSON documents with json_agg/jsonb_agg and json_object_agg/jsonb_object_agg.

For the PostgreSQL documentation on aggregate functions, see this page. The exact translations supported by the provider are documented in the translations page.

Row value expressions

The provider now supports translations which make use of row value expressions, which are conceptually similar to tuples. Row values are particularly useful for implementing keyset pagination, which is much more efficient than the common, offset-base pagination. To learn more about pagination techniques, see this documentation page.

Here's an example comparing two row values as an implementation of keyset pagination:

var nextPage = context.Posts
    .OrderBy(b => b.Date)
    .ThenBy(b => b.PostId)
    .Where(b => EF.Functions.GreaterThan(
        ValueTuple.Create(b.Date, b.PostId),
        ValueTuple.Create(lastDate, lastId)))
    .Take(10)
    .ToList();

This generates the following SQL:

SELECT p."PostId", p."Date"
FROM "Posts" AS p
WHERE (p."Date", p."PostId") > (@__lastDate_1, @__lastId_2)
ORDER BY p."Date", p."PostId"
LIMIT @__p_3

To the list of row value translations, see the translations page.

Other new features

  • Support for PostgreSQL 15 non-distinct NULLs in unique indexes, causing unique constraint violations if a column contains multiple null values. See the documentation for more details.
  • Stored procedure mappings: PostgreSQL support has been added for stored procedure mapping, which is a new feature in EF Core 7.0. See the EF What's new section for documentation. Note that PostgreSQL 14 or above is required to use this feature (for output parameters).

Breaking changes

Note: version 7.0 of the lower-level Npgsql ADO.NET driver, which is used by the EF provider, also has some breaking changes. It's recommended to read the release notes for that as well.

Obsoleted UseXminAsConcurrencyToken

Starting with version 7.0, concurrency token properties can be configured via the standard EF means, rather than the PostgreSQL-specific UseXminAsConcurrencyToken; simply configure any uint property with the IsRowVersion() Fluent API or the [Timestamp] Data Annotation. See the documentation for more details.

Obsoleted default column collations

Versions 6.0 and below had a mechanism that allowed defining a "default column collation", which is applied individually to every text column by default; this differed from the database collation, which is applied once to the database at creation time. This mechanism was introduced because in PostgreSQL, the database collation is quite limited, and for example does not allow specifying non-deterministic collations (e.g. case-insensitive ones).

However, with the introduction of pre-convention model configuration in EF Core, it's now possible to use that generic mechanism for specifying the default collation. As a result, the Npgsql-specific mechanism has been obsoleted and will be removed in a future version.

Default column collations involve the following code:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.UseDefaultColumnCollation("<collation_name>");
}

To switch to the standard EF Core API, replace the code above with the following:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Properties<string>().UseCollation("<collation_name>");
}

Contributors

A big thank you to all the following people who contributed to the 7.0 release!

Milestone 7.0.11

Contributor Assigned issues
@roji 1

Milestone 7.0.4

Contributor Assigned issues
@roji 7

Milestone 7.0.3

Contributor Assigned issues
@jhartmann123 1
@roji 1

Milestone 7.0.1

Contributor Assigned issues
@roji 3

Milestone 7.0.0

Contributor Assigned issues
@roji 35
@midgleyc 1