Skip to content

Commit fea55db

Browse files
CopilotPhenX
andauthored
Fix: Guid PKs bulk-inserted as NULL without explicit ValueGeneratedNever() (#105)
* Initial plan * Fix: include Guid PKs in bulk INSERT by default (unless they have a SQL 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> * Fix: also treat HasDefaultValue() Guid columns as generated; assert Guid ID in merge test * Fix: use FindAnnotation(RelationalAnnotationNames.DefaultValue) instead of GetDefaultValue() for Guid generated check --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PhenX <42170+PhenX@users.noreply.github.com>
1 parent df56b11 commit fea55db

4 files changed

Lines changed: 11 additions & 16 deletions

File tree

src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/ColumnMetadata.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ public ColumnMetadata(IProperty property, SqlDialectBuilder dialect, IComplexPr
2121
QuotedColumName = dialect.Quote(ColumnName);
2222
StoreDefinition = GetStoreDefinition(property);
2323
ClrType = property.ClrType;
24-
IsGenerated = property.ValueGenerated != ValueGenerated.Never;
24+
IsGenerated = property.ValueGenerated != ValueGenerated.Never
25+
&& (property.GetDefaultValueSql() != null
26+
|| property.GetComputedColumnSql() != null
27+
|| property.FindAnnotation(RelationalAnnotationNames.DefaultValue) != null
28+
|| (property.ClrType != typeof(Guid) && property.ClrType != typeof(Guid?)));
2529
}
2630

2731
private readonly Func<object, object?> _getter;

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
3030
.HasConversion(new DateTimeToBinaryConverter());
3131
});
3232

33-
modelBuilder.Entity<TestEntityWithGuidId>(builder =>
34-
{
35-
builder.Property(e => e.Id)
36-
.ValueGeneratedNever();
37-
});
38-
3933
modelBuilder.Entity<TestEntityWithComplexType>(builder =>
4034
{
4135
builder

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Basic/BasicTestsBase.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,12 @@ public async Task InsertEntities_WithGeneratedGuidId(InsertStrategy strategy)
314314
new TestEntityWithGuidId { TestRun = _run, Id = Guid.NewGuid(), Name = $"{_run}_Entity2" }
315315
};
316316

317-
// Act
318-
var insertedEntities = await _context.InsertWithStrategyAsync(strategy, entities, configure => configure.CopyGeneratedColumns = true);
317+
// Act - Guid PKs should be included in INSERT without requiring CopyGeneratedColumns = true
318+
var insertedEntities = await _context.InsertWithStrategyAsync(strategy, entities);
319319

320-
// Assert
320+
// Assert - all fields including the application-assigned Guid Id should be preserved
321321
insertedEntities.Should().BeEquivalentTo(entities,
322-
o=> o
323-
.RespectingRuntimeTypes()
324-
.Excluding(e => e.Id)
325-
);
322+
o => o.RespectingRuntimeTypes());
326323
}
327324

328325
[SkippableTheory]

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Merge/MergeTestsBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ public async Task InsertEntities_MultipleTimes_WithGuidId(InsertStrategy strateg
8787
Update = (inserted, excluded) => inserted,
8888
});
8989

90-
// Assert
90+
// Assert - all fields including the application-assigned Guid Id should be preserved
9191
insertedEntities.Should().BeEquivalentTo(entities,
92-
o => o.RespectingRuntimeTypes().Excluding(e => e.Id));
92+
o => o.RespectingRuntimeTypes());
9393
}
9494

9595
[SkippableTheory]

0 commit comments

Comments
 (0)