From cbb4bd7193140fecad18d8c20828cc71b4610bc4 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 12 Mar 2026 20:06:32 +0200 Subject: [PATCH 1/8] bump version to 10.0.2 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index d338f0f446..03ab29715d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 10.0.1 + 10.0.2 net10.0 latest enable From 12a1aa8ae60554a96711feff4077e7b2c256f1d9 Mon Sep 17 00:00:00 2001 From: Daniel <89273037+7645re@users.noreply.github.com> Date: Mon, 23 Mar 2026 15:25:23 +0300 Subject: [PATCH 2/8] Fix alias cloning for json recordset table-valued functions (#3773) Fixes #3790 (cherry picked from commit fd26075845a09398488ae6e2e68c554145543e4f) --- .../PgTableValuedFunctionExpression.cs | 4 +- .../OwnedJsonCollectionNpgsqlTest.cs | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/EFCore.PG/Query/Expressions/Internal/PgTableValuedFunctionExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PgTableValuedFunctionExpression.cs index 86bcd95d9e..dd035d2ca4 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PgTableValuedFunctionExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PgTableValuedFunctionExpression.cs @@ -89,7 +89,9 @@ public override TableExpressionBase Clone(string? alias, ExpressionVisitor cloni arguments[i] = (SqlExpression)cloningExpressionVisitor.Visit(Arguments[i]); } - return new PgTableValuedFunctionExpression(Alias, Name, arguments, ColumnInfos, WithOrdinality); + // Without ColumnInfos (e.g. unnest), PostgreSQL ties the output column name to the table alias, so preserve it. + // With explicit ColumnInfos (e.g. jsonb_to_recordset), apply the clone alias to keep FROM references consistent. + return new PgTableValuedFunctionExpression(ColumnInfos is null ? Alias : alias!, Name, arguments, ColumnInfos, WithOrdinality); } /// diff --git a/test/EFCore.PG.FunctionalTests/Query/Associations/OwnedJson/OwnedJsonCollectionNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/Associations/OwnedJson/OwnedJsonCollectionNpgsqlTest.cs index 17195be35c..26fa6bdf2d 100644 --- a/test/EFCore.PG.FunctionalTests/Query/Associations/OwnedJson/OwnedJsonCollectionNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/Associations/OwnedJson/OwnedJsonCollectionNpgsqlTest.cs @@ -238,6 +238,60 @@ GROUP BY a0."Key" """); } + [ConditionalFact] + public virtual async Task GroupBy_with_json_collection_predicate_and_projecting_group_elements() + { + await using var context = Fixture.CreateContext(); + + var result = await context.Set() + .Where(root => root.AssociateCollection.Any(element => element.Int > 0)) + .GroupBy(root => root.Name) + .Select(group => new { Elements = group.OrderBy(root => root.Id).Take(1) }) + .ToListAsync(); + + Assert.NotEmpty(result); + Assert.All(result, grouping => Assert.NotNull(grouping.Elements)); + + AssertSql( + """ +SELECT r1."Name", r3."Id", r3."Name", r3.c, r3.c0, r3.c1 +FROM ( + SELECT r."Name" + FROM "RootEntity" AS r + WHERE EXISTS ( + SELECT 1 + FROM ROWS FROM (jsonb_to_recordset(r."AssociateCollection") AS ( + "Id" integer, + "Int" integer, + "Ints" jsonb, + "Name" text, + "String" text + )) WITH ORDINALITY AS a + WHERE a."Int" > 0) + GROUP BY r."Name" +) AS r1 +LEFT JOIN ( + SELECT r2."Id", r2."Name", r2.c, r2.c0, r2.c1 + FROM ( + SELECT r0."Id", r0."Name", r0."AssociateCollection" AS c, r0."OptionalAssociate" AS c0, r0."RequiredAssociate" AS c1, ROW_NUMBER() OVER(PARTITION BY r0."Name" ORDER BY r0."Id" NULLS FIRST) AS row + FROM "RootEntity" AS r0 + WHERE EXISTS ( + SELECT 1 + FROM ROWS FROM (jsonb_to_recordset(r0."AssociateCollection") AS ( + "Id" integer, + "Int" integer, + "Ints" jsonb, + "Name" text, + "String" text + )) WITH ORDINALITY AS a0 + WHERE a0."Int" > 0) + ) AS r2 + WHERE r2.row <= 1 +) AS r3 ON r1."Name" = r3."Name" +ORDER BY r1."Name" NULLS FIRST, r3."Name" NULLS FIRST, r3."Id" NULLS FIRST +"""); + } + #endregion GroupBy public override async Task Select_within_Select_within_Select_with_aggregates() From 632d7fb2e0bf10df5a3b3ed7d923da8aeef7ed34 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:50:38 +0300 Subject: [PATCH 3/8] Fix NpgsqlOptionsExtension losing ParameterizedCollectionMode between clones (#3796) Fixes #3795 Co-authored-by: Shay Rojansky (cherry picked from commit 9119f83bb0b5892dd225197ec9280c729431c0d9) --- .../Internal/NpgsqlOptionsExtension.cs | 1 + .../NpgsqlDbContextOptionsExtensionsTest.cs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs b/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs index db0796f2d4..5f61329fee 100644 --- a/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs +++ b/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs @@ -126,6 +126,7 @@ public NpgsqlOptionsExtension(NpgsqlOptionsExtension copyFrom) DataSourceBuilderAction = copyFrom.DataSourceBuilderAction; AdminDatabase = copyFrom.AdminDatabase; _postgresVersion = copyFrom._postgresVersion; + _parameterizedCollectionMode = copyFrom._parameterizedCollectionMode; UseRedshift = copyFrom.UseRedshift; _userRangeDefinitions = [..copyFrom._userRangeDefinitions]; _enumDefinitions = [..copyFrom._enumDefinitions]; diff --git a/test/EFCore.PG.Tests/NpgsqlDbContextOptionsExtensionsTest.cs b/test/EFCore.PG.Tests/NpgsqlDbContextOptionsExtensionsTest.cs index 93c749fcb2..27d4446bd0 100644 --- a/test/EFCore.PG.Tests/NpgsqlDbContextOptionsExtensionsTest.cs +++ b/test/EFCore.PG.Tests/NpgsqlDbContextOptionsExtensionsTest.cs @@ -26,6 +26,21 @@ public void Can_add_extension_with_command_timeout() Assert.Equal(30, extension.CommandTimeout); } + [ConditionalFact] + public void ParameterizedCollectionMode_is_preserved_after_clone() + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseNpgsql("Database=Crunchie", b => + { + b.UseParameterizedCollectionMode(ParameterTranslationMode.MultipleParameters); + b.UseRelationalNulls(); + }); + + var extension = optionsBuilder.Options.Extensions.OfType().Single(); + + Assert.Equal(ParameterTranslationMode.MultipleParameters, extension.ParameterizedCollectionMode); + } + [ConditionalFact] public void Can_add_extension_with_connection_string() { From a3602442ce77843b58da4e47a836f07e76d3fce0 Mon Sep 17 00:00:00 2001 From: Daniel Kottis Date: Thu, 2 Apr 2026 17:35:33 +0200 Subject: [PATCH 4/8] Filter out extension-related operations in creation scripts of history table (#3713) Fixes #3496 Co-authored-by: Shay Rojansky (cherry picked from commit 8237cba48a1bc3757c4fc05e5e7804d103639d81) --- .../Internal/NpgsqlHistoryRepository.cs | 46 ++++++++++--- .../Migrations/NpgsqlHistoryRepositoryTest.cs | 67 +++++++++++++++++++ 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs b/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs index c2834eed5f..a79ae8bc36 100644 --- a/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs +++ b/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs @@ -1,4 +1,5 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Conventions; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Internal; namespace Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Internal; @@ -101,14 +102,40 @@ protected override IReadOnlyList GetCreateCommands() { // TODO: This is all a hack around https://github.com/dotnet/efcore/issues/34991: we have provider-specific conventions which add // enums and extensions to the model, and the default EF logic causes them to be created at this point, when the history table is - // being created. + // being created. This causes problems when: + // (a) we create an enum here when creating the history table, and then try to create it again when the actual migration + // runs (#3324), and + // (b) we shouldn't be creating extensions at this early point either, and doing so can cause issues (e.g. #3496). + // + // So we filter out any extension/enum migration operations. + // Note that the approach in EF is to remove specific conventions (e.g. DbSetFindingConvention), but we don't want to hardcode + // specific conventions here; for example, the NetTopologySuite plugin has its NpgsqlNetTopologySuiteExtensionAddingConvention + // which adds PostGIS. So we just filter out the annotations on the operations themselves. var model = EnsureModel(); var operations = Dependencies.ModelDiffer.GetDifferences(null, model.GetRelationalModel()); - var commandList = Dependencies.MigrationsSqlGenerator.Generate(operations, model); - return commandList; + + foreach (var operation in operations) + { + if (operation is not AlterDatabaseOperation alterDatabaseOperation) + { + continue; + } + + foreach (var annotation in alterDatabaseOperation.GetAnnotations()) + { + if (annotation.Name.StartsWith(NpgsqlAnnotationNames.PostgresExtensionPrefix, StringComparison.Ordinal) + || annotation.Name.StartsWith(NpgsqlAnnotationNames.EnumPrefix, StringComparison.Ordinal)) + { + alterDatabaseOperation.RemoveAnnotation(annotation.Name); + } + } + } + + return Dependencies.MigrationsSqlGenerator.Generate(operations, model); } + // Copied as-is from EF's HistoryRepository, since it's private (see https://github.com/dotnet/efcore/issues/34991) private IModel EnsureModel() { if (_model == null) @@ -117,16 +144,13 @@ private IModel EnsureModel() conventionSet.Remove(typeof(DbSetFindingConvention)); conventionSet.Remove(typeof(RelationalDbFunctionAttributeConvention)); - // TODO: this whole method exists only so we can remove this convention (https://github.com/dotnet/efcore/issues/34991) - conventionSet.Remove(typeof(NpgsqlPostgresModelFinalizingConvention)); var modelBuilder = new ModelBuilder(conventionSet); - modelBuilder.Entity( - x => - { - ConfigureTable(x); - x.ToTable(TableName, TableSchema); - }); + modelBuilder.Entity(x => + { + ConfigureTable(x); + x.ToTable(TableName, TableSchema); + }); _model = Dependencies.ModelRuntimeInitializer.Initialize( (IModel)modelBuilder.Model, designTime: true, validationLogger: null); diff --git a/test/EFCore.PG.Tests/Migrations/NpgsqlHistoryRepositoryTest.cs b/test/EFCore.PG.Tests/Migrations/NpgsqlHistoryRepositoryTest.cs index 0462716483..fbb8324f80 100644 --- a/test/EFCore.PG.Tests/Migrations/NpgsqlHistoryRepositoryTest.cs +++ b/test/EFCore.PG.Tests/Migrations/NpgsqlHistoryRepositoryTest.cs @@ -77,6 +77,73 @@ IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'my') THEN CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") ); +""", sql, ignoreLineEndingDifferences: true); + } + + [ConditionalFact] + public void GetCreateIfNotExistsScript_does_not_include_extensions() + { + var historyRepository = new TestDbContext( + new DbContextOptionsBuilder() + .UseInternalServiceProvider( + NpgsqlTestHelpers.Instance.CreateServiceProvider( + new ServiceCollection().AddEntityFrameworkNpgsqlNetTopologySuite())) + .UseNpgsql( + new NpgsqlConnection("Host=localhost;Database=DummyDatabase"), + b => b.MigrationsHistoryTable(HistoryRepository.DefaultTableName, "some_schema") + .UseNetTopologySuite()) + .Options) + .GetService();; + + var sql = historyRepository.GetCreateIfNotExistsScript(); + + Assert.Equal( + """ +DO $EF$ +BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'some_schema') THEN + CREATE SCHEMA some_schema; + END IF; +END $EF$; +CREATE TABLE IF NOT EXISTS some_schema."__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL, + CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") +); + +""", sql, ignoreLineEndingDifferences: true); + } + + enum TestEnum { Value1, Value2 } + + [ConditionalFact] + public void GetCreateIfNotExistsScript_does_not_include_enums() + { + var historyRepository = new TestDbContext( + new DbContextOptionsBuilder() + .UseNpgsql( + new NpgsqlConnection("Host=localhost;Database=DummyDatabase"), + b => b.MigrationsHistoryTable(HistoryRepository.DefaultTableName, "some_schema") + .MapEnum("test_enum")) + .Options) + .GetService();; + + var sql = historyRepository.GetCreateIfNotExistsScript(); + + Assert.Equal( + """ +DO $EF$ +BEGIN + IF NOT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'some_schema') THEN + CREATE SCHEMA some_schema; + END IF; +END $EF$; +CREATE TABLE IF NOT EXISTS some_schema."__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL, + CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") +); + """, sql, ignoreLineEndingDifferences: true); } From caeb33bfa7933ace805ae1d381ea6f900bb75a44 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 24 Dec 2025 14:34:59 +0100 Subject: [PATCH 5/8] Allow null connection string with ConfigureDataSource (#3693) Fixes #3692 (cherry picked from commit a64c405a87ae89311213eafc71f250202ddc8e13) --- .../Internal/NpgsqlDataSourceManager.cs | 34 ++++++++++++------- .../BadDataJsonDeserializationNpgsqlTest.cs | 2 +- .../NpgsqlRelationalConnectionTest.cs | 13 ++++++- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlDataSourceManager.cs b/src/EFCore.PG/Storage/Internal/NpgsqlDataSourceManager.cs index bd67b76899..ec07ae1bd7 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlDataSourceManager.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlDataSourceManager.cs @@ -65,29 +65,37 @@ public NpgsqlDataSourceManager(IEnumerable // must be manually set up by the user for the enum, of course). { Connection: not null } => null, - // If the user hasn't configured anything in UseNpgsql (no data source, no connection, no connection string), check the - // application service provider to see if a data source is registered there, and return that. - { ConnectionString: null } when applicationServiceProvider?.GetService() is DbDataSource dataSource - => dataSource, - - // Otherwise if there's no connection string, abort: a connection string is required to create a data source in any case. - { ConnectionString: null } or null => null, + // If a data source builder action is specified, always create a data source. + { DataSourceBuilderAction: not null } o => GetSingletonDataSource(o), + + // If the user hasn't configured anything in UseNpgsql (no data source, no data source builder action, no connection, + // no connection string), check the application service provider to see if a data source is registered there, and return that. + // Otherwise if there's no connection string, abort: either a connection string or DataSourceBuilderAction is required + // to create a data source in any case. + { ConnectionString: null } or null + => applicationServiceProvider?.GetService() is DbDataSource dataSource + ? dataSource + : null, // The following are features which require an NpgsqlDataSource, since they require configuration on NpgsqlDataSourceBuilder. - { DataSourceBuilderAction: not null } => GetSingletonDataSource(npgsqlOptionsExtension), - { EnumDefinitions.Count: > 0 } => GetSingletonDataSource(npgsqlOptionsExtension), - _ when _plugins.Any() => GetSingletonDataSource(npgsqlOptionsExtension), + { EnumDefinitions.Count: > 0 } o => GetSingletonDataSource(o), + { } o when _plugins.Any() => GetSingletonDataSource(o), // If there's no configured feature which requires us to use a data source internally, don't use one; this causes - // NpgsqlRelationalConnection to use the connection string as before (no data source), allowing switching connection strings - // with the same service provider etc. + // NpgsqlRelationalConnection to use the connection string as before (no data source at the EF level), allowing switching + // connection strings with the same service provider etc. _ => null }; private DbDataSource GetSingletonDataSource(NpgsqlOptionsExtension npgsqlOptionsExtension) { var connectionString = npgsqlOptionsExtension.ConnectionString; - Check.DebugAssert(connectionString is not null, "Connection string can't be null"); + + // It should be possible to use ConfigureDataSource() without supplying a connection string, providing the connection + // information via the connection string builder on the NpgsqlDataSourceBuilder. In order to support this, we + // coalesce null connection strings to empty strings (since dictionaries don't allow null keys). + // This is in line with general ADO.NET practice of coalescing null connection strings to empty strings. + connectionString ??= string.Empty; if (_dataSources.TryGetValue(connectionString, out var dataSource)) { diff --git a/test/EFCore.PG.FunctionalTests/BadDataJsonDeserializationNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/BadDataJsonDeserializationNpgsqlTest.cs index 03a04d59fe..eacc8e7243 100644 --- a/test/EFCore.PG.FunctionalTests/BadDataJsonDeserializationNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/BadDataJsonDeserializationNpgsqlTest.cs @@ -1,6 +1,6 @@ namespace Microsoft.EntityFrameworkCore; -public class BadDataJsonDeserializationSqlServerTest : BadDataJsonDeserializationTestBase +public class BadDataJsonDeserializationNpgsqlTest : BadDataJsonDeserializationTestBase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => base.OnConfiguring(optionsBuilder.UseNpgsql(b => b.UseNetTopologySuite())); diff --git a/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs b/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs index ce41173e58..5f8f170e44 100644 --- a/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs +++ b/test/EFCore.PG.Tests/NpgsqlRelationalConnectionTest.cs @@ -159,6 +159,17 @@ public void Data_source_config_with_same_connection_string_and_different_lambda( Assert.Same(connection1.DbDataSource, connection2.DbDataSource); } + [Fact] + public void Data_source_config_without_a_connection_string() + { + var context = new ConfigurableContext( + connectionString: null, + no => no.ConfigureDataSource(dsb => dsb.ConnectionStringBuilder.Host = "192.168.1.1")); + var connection1 = (NpgsqlRelationalConnection)context.GetService(); + Assert.Equal("Host=192.168.1.1", connection1.ConnectionString); + Assert.NotNull(connection1.DbDataSource); + } + [Fact] public void Plugin_config_with_same_connection_string() { @@ -439,7 +450,7 @@ public FakeDbContext(DbContextOptions options) } } - private class ConfigurableContext(string connectionString, Action? npgsqlOptionsAction = null) : DbContext + private class ConfigurableContext(string? connectionString, Action? npgsqlOptionsAction = null) : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(connectionString, npgsqlOptionsAction); From 7ce26dd25666d9e677811629fc5eb9eab40ea496 Mon Sep 17 00:00:00 2001 From: Georg Jung Date: Sun, 26 Apr 2026 13:16:29 +0200 Subject: [PATCH 6/8] Translate `bytea.Any()` as `length > 0` (#3817) Fixes #3816 --- src/EFCore.PG/Internal/EnumerableMethods.cs | 7 ++++--- .../Internal/NpgsqlByteArrayMethodTranslator.cs | 12 ++++++++++++ .../ByteArrayTranslationsNpgsqlTest.cs | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/EFCore.PG/Internal/EnumerableMethods.cs b/src/EFCore.PG/Internal/EnumerableMethods.cs index 3d86265345..de3799fa17 100644 --- a/src/EFCore.PG/Internal/EnumerableMethods.cs +++ b/src/EFCore.PG/Internal/EnumerableMethods.cs @@ -10,7 +10,7 @@ internal static class EnumerableMethods public static MethodInfo All { get; } - // public static MethodInfo AnyWithoutPredicate { get; } + public static MethodInfo AnyWithoutPredicate { get; } public static MethodInfo AnyWithPredicate { get; } @@ -259,8 +259,9 @@ static EnumerableMethods() nameof(Enumerable.All), 1, types => [typeof(IEnumerable<>).MakeGenericType(types[0]), typeof(Func<,>).MakeGenericType(types[0], typeof(bool))]); - // AnyWithoutPredicate = GetMethod(nameof(Enumerable.Any), 1, - // types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) }); + AnyWithoutPredicate = GetMethod( + nameof(Enumerable.Any), 1, + types => [typeof(IEnumerable<>).MakeGenericType(types[0])]); AnyWithPredicate = GetMethod( nameof(Enumerable.Any), 1, diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs index 4a6a226593..d16b608c45 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs @@ -79,6 +79,18 @@ public NpgsqlByteArrayMethodTranslator(ISqlExpressionFactory sqlExpressionFactor _sqlExpressionFactory.Constant(0)); } + if (method.GetGenericMethodDefinition().Equals(EnumerableMethods.AnyWithoutPredicate)) + { + return _sqlExpressionFactory.GreaterThan( + _sqlExpressionFactory.Function( + "length", + [arguments[0]], + nullable: true, + argumentsPropagateNullability: TrueArrays[1], + typeof(int)), + _sqlExpressionFactory.Constant(0)); + } + if (method.GetGenericMethodDefinition().Equals(EnumerableMethods.FirstWithoutPredicate)) { return _sqlExpressionFactory.Convert( diff --git a/test/EFCore.PG.FunctionalTests/Query/Translations/ByteArrayTranslationsNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/Translations/ByteArrayTranslationsNpgsqlTest.cs index c280c208d6..5ccd996d0e 100644 --- a/test/EFCore.PG.FunctionalTests/Query/Translations/ByteArrayTranslationsNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/Translations/ByteArrayTranslationsNpgsqlTest.cs @@ -1,3 +1,5 @@ +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + namespace Microsoft.EntityFrameworkCore.Query.Translations; public class ByteArrayTranslationsNpgsqlTest : ByteArrayTranslationsTestBase @@ -98,6 +100,19 @@ public override async Task SequenceEqual() """); } + [ConditionalFact] + public virtual async Task Any() + { + await AssertQuery(ss => ss.Set().Where(e => e.ByteArray.Any())); + + AssertSql( +""" +SELECT b."Id", b."Bool", b."Byte", b."ByteArray", b."DateOnly", b."DateTime", b."DateTimeOffset", b."Decimal", b."Double", b."Enum", b."FlagsEnum", b."Float", b."Guid", b."Int", b."Long", b."Short", b."String", b."TimeOnly", b."TimeSpan" +FROM "BasicTypesEntities" AS b +WHERE length(b."ByteArray") > 0 +"""); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); } From b09f306aeef5816e3ce0ea83dee0f9165f07b85a Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 1 May 2026 00:50:32 +0200 Subject: [PATCH 7/8] Fix nullability of IncludeProperties includeExpression parameter (#3826) Fixes #3825 (cherry picked from commit dda4c32421447e304aa494e7b350fb983e38f3ea) --- .../BuilderExtensions/NpgsqlIndexBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs index 741bff72a3..14153b5d71 100644 --- a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs @@ -526,7 +526,7 @@ public static IndexBuilder IncludeProperties( /// A builder to further configure the index. public static IndexBuilder IncludeProperties( this IndexBuilder indexBuilder, - Expression> includeExpression) + Expression> includeExpression) { Check.NotNull(indexBuilder, nameof(indexBuilder)); Check.NotNull(includeExpression, nameof(includeExpression)); From c46789c136fa63fe5a97577f79c54e1c0ec0e9ef Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Wed, 27 May 2026 14:36:06 +0200 Subject: [PATCH 8/8] Use Npgsql 10.0.3 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2b0ae502f0..c6123aba9a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,7 +2,7 @@ 10.0.4 10.0.4 - 10.0.2 + 10.0.3