diff --git a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Configurations/EntityAConfiguration.cs b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Configurations/EntityAConfiguration.cs index 3d34ccc..3f1b213 100644 --- a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Configurations/EntityAConfiguration.cs +++ b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Configurations/EntityAConfiguration.cs @@ -27,5 +27,14 @@ protected override void EntityConfigure(EntityTypeBuilder builder) }); builder.Property(e => e.Value) .IsRequired(); + builder.OwnsOne( + e => e.Money, + money => + { + money.Property(m => m.Amount) + .IsRequired(); + money.Property(m => m.Currency) + .IsRequired(); + }); } } \ No newline at end of file diff --git a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Entities/EntityA.cs b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Entities/EntityA.cs index c695fe2..688420c 100644 --- a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Entities/EntityA.cs +++ b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/Entities/EntityA.cs @@ -1,4 +1,5 @@ using Codehard.Common.DomainModel; +using Codehard.Common.DomainModel.Types; namespace Codehard.Infrastructure.EntityFramework.Tests.Entities; @@ -28,7 +29,11 @@ public class EntityA : Entity public override EntityAKey Id { get; protected init; } public string Value { get; set; } = string.Empty; - + + public Money? NullableMoney { get; set; } + + public Money? Money { get; set; } = new(0, Currency.Thb); + public void UpdateValue(string newValue) { this.Value = newValue; diff --git a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/MoneyTypeTests.cs b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/MoneyTypeTests.cs new file mode 100644 index 0000000..5334daa --- /dev/null +++ b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework.Tests/MoneyTypeTests.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using Codehard.Infrastructure.EntityFramework.Extensions; +using Codehard.Infrastructure.EntityFramework.Tests.Entities; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Moq; + +namespace Codehard.Infrastructure.EntityFramework.Tests; + +public class MoneyTypeTests +{ + private static SqliteConnection CreateInMemoryDatabase() + { + var connection = new SqliteConnection("DataSource=:memory:"); + connection.Open(); + return connection; + } + + [Fact] + public async void WhenAddNewEntity_ShouldPersistedToDb() + { + // Arrange + var options = new DbContextOptionsBuilder() + .UseSqlite(CreateInMemoryDatabase()) + .Options; + + var assembly = Assembly.GetExecutingAssembly(); + + var loggerMock = new Mock>(); + var logger = loggerMock.Object; + + await using var context = new TestDbContext( + options, + builder => builder.ApplyConfigurationsFromAssemblyFor(assembly), + logger); + + await context.Database.EnsureCreatedAsync(); + + // Act + var newEntity = EntityA.Create(); + + context.As.Add(newEntity); + context.SaveChanges(); + context.Entry(newEntity).State = EntityState.Detached; + + // Assert + var actual = + context.As + .Include(entityA => entityA.NullableMoney) + .Include(entityA => entityA.Money) + .First(); + + Assert.Null(actual.NullableMoney); + Assert.NotNull(actual.Money); + Assert.Equal(0, actual.Money.Amount); + } +} \ No newline at end of file diff --git a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework/Extensions/ChangeTrackingExtensions.cs b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework/Extensions/ChangeTrackingExtensions.cs index 4172172..74a872f 100644 --- a/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework/Extensions/ChangeTrackingExtensions.cs +++ b/src/Codehard.Infrastructure/Codehard.Infrastructure.EntityFramework/Extensions/ChangeTrackingExtensions.cs @@ -242,6 +242,8 @@ private static void UpdateIfChanged( SetItemAsDeleted(itemsToRemove); SetItemAsModified(itemsToModify); + return; + IEnumerable CastToIEnumerable(object? collection) { // Get the Cast() method from the Enumerable class using reflection