diff --git a/src/EFCore.PG/ValueGeneration/Internal/NpgsqlValueGeneratorSelector.cs b/src/EFCore.PG/ValueGeneration/Internal/NpgsqlValueGeneratorSelector.cs
index a9274f617..808532b42 100644
--- a/src/EFCore.PG/ValueGeneration/Internal/NpgsqlValueGeneratorSelector.cs
+++ b/src/EFCore.PG/ValueGeneration/Internal/NpgsqlValueGeneratorSelector.cs
@@ -101,9 +101,14 @@ public override bool TrySelect(IProperty property, ITypeBase typeBase, out Value
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
protected override ValueGenerator? FindForType(IProperty property, ITypeBase typeBase, Type clrType)
- => property.ClrType.UnwrapNullableType() == typeof(Guid)
- ? property.ValueGenerated == ValueGenerated.Never || property.GetDefaultValueSql() is not null
- ? new TemporaryGuidValueGenerator()
- : new NpgsqlSequentialGuidValueGenerator()
- : base.FindForType(property, typeBase, clrType);
+ => property.ClrType.UnwrapNullableType() switch
+ {
+ var t when t == typeof(Guid) && property.ValueGenerated is not ValueGenerated.Never && property.GetDefaultValueSql() is null
+ => new NpgsqlSequentialGuidValueGenerator(),
+
+ var t when t == typeof(string) && property.ValueGenerated is not ValueGenerated.Never && property.GetDefaultValueSql() is null
+ => new NpgsqlSequentialStringValueGenerator(),
+
+ _ => base.FindForType(property, typeBase, clrType)
+ };
}
diff --git a/src/EFCore.PG/ValueGeneration/NpgsqlSequentialStringValueGenerator.cs b/src/EFCore.PG/ValueGeneration/NpgsqlSequentialStringValueGenerator.cs
new file mode 100644
index 000000000..8c4f595dc
--- /dev/null
+++ b/src/EFCore.PG/ValueGeneration/NpgsqlSequentialStringValueGenerator.cs
@@ -0,0 +1,22 @@
+namespace Npgsql.EntityFrameworkCore.PostgreSQL.ValueGeneration;
+
+///
+/// This API supports the Entity Framework Core infrastructure and is not intended to be used
+/// directly from your code. This API may change or be removed in future releases.
+///
+public class NpgsqlSequentialStringValueGenerator : ValueGenerator
+{
+ private readonly NpgsqlSequentialGuidValueGenerator _guidGenerator = new();
+
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
+ public override bool GeneratesTemporaryValues => false;
+
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
+ public override string Next(EntityEntry entry) => _guidGenerator.Next(entry).ToString();
+}
diff --git a/test/EFCore.PG.Tests/NpgsqlValueGeneratorSelectorTest.cs b/test/EFCore.PG.Tests/NpgsqlValueGeneratorSelectorTest.cs
index 57b0d1b9a..9b6b3ae42 100644
--- a/test/EFCore.PG.Tests/NpgsqlValueGeneratorSelectorTest.cs
+++ b/test/EFCore.PG.Tests/NpgsqlValueGeneratorSelectorTest.cs
@@ -21,7 +21,7 @@ public void Returns_built_in_generators_for_types_setup_for_value_generation()
AssertGenerator("NullableShort");
AssertGenerator("NullableByte");
AssertGenerator("Decimal");
- AssertGenerator("String");
+ AssertGenerator("String");
AssertGenerator("Guid");
AssertGenerator("Binary");
}
@@ -128,7 +128,7 @@ public void Returns_sequence_value_generators_when_configured_for_model()
AssertGenerator>("NullableInt", setSequences: true);
AssertGenerator>("NullableLong", setSequences: true);
AssertGenerator>("NullableShort", setSequences: true);
- AssertGenerator("String", setSequences: true);
+ AssertGenerator("String", setSequences: true);
AssertGenerator("Guid", setSequences: true);
AssertGenerator("Binary", setSequences: true);
}