diff --git a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs index beee387..f66a813 100644 --- a/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs +++ b/src/PhenX.EntityFrameworkCore.BulkInsert/Metadata/PropertyAccessor.cs @@ -64,7 +64,8 @@ internal static class PropertyAccessor // instance => converter(body) var invokeConverter = Expression.Invoke(converter, converterInput); - if (body.Type.IsClass) + // If the property is a reference type, we need to check for null before calling the converter + if (body.Type.IsClass && !invokeConverter.Type.IsValueType) { // instance => body == null ? null : converter(body) var nullCondition = Expression.Equal(body, Expression.Constant(null, body.Type)); diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs index f40911b..c4835a5 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestDbContext.cs @@ -1,6 +1,8 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using SmartEnum.EFCore; + namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; public class TestDbContext : TestDbContextBase @@ -11,6 +13,7 @@ public class TestDbContext : TestDbContextBase public DbSet TestEntitiesWithGuidId { get; set; } = null!; public DbSet TestEntitiesWithConverter { get; set; } = null!; public DbSet TestEntitiesWithComplexType { get; set; } = null!; + public DbSet TestEntitiesWithSmartEnum { get; set; } = null!; public DbSet Students { get; set; } = null!; public DbSet Courses { get; set; } = null!; @@ -18,6 +21,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); + modelBuilder.ConfigureSmartEnum(); + modelBuilder.Entity(builder => { builder.Property(e => e.CreatedAt) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithSmartEnum.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithSmartEnum.cs new file mode 100644 index 0000000..11a8eef --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestEntityWithSmartEnum.cs @@ -0,0 +1,11 @@ +using Microsoft.EntityFrameworkCore; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +[PrimaryKey(nameof(Id))] +public class TestEntityWithSmartEnum : TestEntityBase +{ + public int Id { get; set; } + + public TestSmartEnum Enum { get; set; } = null!; +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestSmartEnum.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestSmartEnum.cs new file mode 100644 index 0000000..02aad51 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/DbContext/TestSmartEnum.cs @@ -0,0 +1,12 @@ +using Ardalis.SmartEnum; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +public class TestSmartEnum : SmartEnum +{ + private TestSmartEnum(string name, int value) : base(name, value) + { + } + + public static readonly TestSmartEnum Value = new TestSmartEnum("test", 1); +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/PhenX.EntityFrameworkCore.BulkInsert.Tests.csproj b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/PhenX.EntityFrameworkCore.BulkInsert.Tests.csproj index 553af61..9ffca17 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/PhenX.EntityFrameworkCore.BulkInsert.Tests.csproj +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/PhenX.EntityFrameworkCore.BulkInsert.Tests.csproj @@ -44,6 +44,10 @@ + + + + diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsBase.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsBase.cs new file mode 100644 index 0000000..e3769f5 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsBase.cs @@ -0,0 +1,45 @@ +using FluentAssertions; + +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +public abstract class VariousTestsBase(TestDbContainer dbContainer) : IAsyncLifetime + where TDbContext : TestDbContext, new() +{ + private readonly Guid _run = Guid.NewGuid(); + private TDbContext _context = null!; + + public async Task InitializeAsync() + { + _context = await dbContainer.CreateContextAsync("various"); + } + + public Task DisposeAsync() + { + _context.Dispose(); + return Task.CompletedTask; + } + + [SkippableTheory] + [CombinatorialData] + public async Task InsertSmartEnumEntities(InsertStrategy strategy) + { + // Arrange + var entities = new List + { + new TestEntityWithSmartEnum { TestRun = _run, Enum = TestSmartEnum.Value}, + new TestEntityWithSmartEnum { TestRun = _run, Enum = TestSmartEnum.Value} + }; + + // Act + var insertedEntities = await _context.InsertWithStrategyAsync(strategy, entities); + + // Assert + insertedEntities.Should().BeEquivalentTo(entities, + o => o.RespectingRuntimeTypes().Excluding(e => e.Id)); + } +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsMySql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsMySql.cs new file mode 100644 index 0000000..30e2a8d --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsMySql.cs @@ -0,0 +1,12 @@ +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +[Trait("Category", "MySql")] +[Collection(TestDbContainerMySqlCollection.Name)] +public class VariousTestsMySql(TestDbContainerMySql dbContainer) : VariousTestsBase(dbContainer) +{ +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsOracle.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsOracle.cs new file mode 100644 index 0000000..8a0361d --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsOracle.cs @@ -0,0 +1,12 @@ +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +[Trait("Category", "Oracle")] +[Collection(TestDbContainerOracleCollection.Name)] +public class VariousTestsOracle(TestDbContainerOracle dbContainer) : VariousTestsBase(dbContainer) +{ +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsPostgreSql.cs new file mode 100644 index 0000000..099c3f6 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsPostgreSql.cs @@ -0,0 +1,12 @@ +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +[Trait("Category", "PostgreSql")] +[Collection(TestDbContainerPostgreSqlCollection.Name)] +public class VariousTestsPostgreSql(TestDbContainerPostgreSql dbContainer) : VariousTestsBase(dbContainer) +{ +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlServer.cs new file mode 100644 index 0000000..b9ae700 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlServer.cs @@ -0,0 +1,12 @@ +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +[Trait("Category", "SqlServer")] +[Collection(TestDbContainerSqlServerCollection.Name)] +public class VariousTestsSqlServer(TestDbContainerSqlServer dbContainer) : VariousTestsBase(dbContainer) +{ +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlite.cs new file mode 100644 index 0000000..21e0055 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/Tests/Various/VariousTestsSqlite.cs @@ -0,0 +1,12 @@ +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContainer; +using PhenX.EntityFrameworkCore.BulkInsert.Tests.DbContext; + +using Xunit; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Tests.Tests.Various; + +[Trait("Category", "Sqlite")] +[Collection(TestDbContainerSqliteCollection.Name)] +public class VariousTestsSqlite(TestDbContainerSqlite dbContainer) : VariousTestsBase(dbContainer) +{ +}