Fix: Guid PKs bulk-inserted as NULL without explicit ValueGeneratedNever()#105
Conversation
…QL default/computed expression) Agent-Logs-Url: https://github.com/PhenX/PhenX.EntityFrameworkCore.BulkInsert/sessions/aa61e1ea-a4c4-4114-857f-cd0d547277d4 Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes bulk insert handling for EF Core’s default Guid primary key metadata by treating application-assigned Guid keys as insertable unless they have explicit database generation metadata.
Changes:
- Refines
ColumnMetadata.IsGeneratedso default Guid/Guid?ValueGenerated.OnAddcolumns are not automatically excluded from inserts. - Removes the test-only
ValueGeneratedNever()workaround forTestEntityWithGuidId. - Updates the basic Guid key insert test to assert the assigned Guid IDs are preserved.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/ColumnMetadata.cs |
Updates generated-column detection for Guid/Guid? properties. |
tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs |
Removes explicit Guid key generation override from test model configuration. |
tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs |
Adjusts Guid key bulk insert test expectations and options. |
| && (property.GetDefaultValueSql() != null | ||
| || property.GetComputedColumnSql() != null | ||
| || (property.ClrType != typeof(Guid) && property.ClrType != typeof(Guid?))); |
| insertedEntities.Should().BeEquivalentTo(entities, | ||
| o=> o | ||
| .RespectingRuntimeTypes() | ||
| .Excluding(e => e.Id) | ||
| ); | ||
| o => o.RespectingRuntimeTypes()); |
|
@copilot take the review into account |
…uid ID in merge test
…ad of GetDefaultValue() for Guid generated check
Both review points are addressed:
|
EF Core defaults Guid primary keys to
ValueGenerated.OnAdd(client-side generation). The library was treating allValueGenerated != Neverproperties as "database-generated" and excluding them from the INSERT column list, causing NULL to be inserted for Guid PKs unlessValueGeneratedNever()was explicitly configured.Changes
ColumnMetadata.cs:IsGeneratedno longer marksGuid/Guid?columns as generated unless they carry an explicit SQL default expression (GetDefaultValueSql()), are computed columns (GetComputedColumnSql()), or have a CLR-level default explicitly configured viaHasDefaultValue(...)(detected viaFindAnnotation(RelationalAnnotationNames.DefaultValue)). Non-Guid auto-increment columns (SQL ServerIDENTITY, SQLite integer PK) are unaffected.TestDbContext.cs: Removed theValueGeneratedNever()workaround fromTestEntityWithGuidId— the entity now works correctly by default.BasicTestsBase.cs: UpdatedInsertEntities_WithGeneratedGuidIdto remove theCopyGeneratedColumns = trueworkaround and assert that application-assigned Guid values are preserved end-to-end.MergeTestsBase.cs: UpdatedInsertEntities_MultipleTimes_WithGuidIdto assert that the application-assigned GuidIdis preserved through the merge/on-conflict path (removed.Excluding(e => e.Id)from the equivalence check).Before / After
A Guid column with an explicit database default (e.g.
HasDefaultValueSql("NEWID()")orHasDefaultValue(someGuid)) continues to be treated as generated and excluded from INSERT by default.