From 21759b39f29591ec6fd4c12d5d2590c3bb15ca37 Mon Sep 17 00:00:00 2001 From: maliming <6908465+maliming@users.noreply.github.com> Date: Thu, 17 Sep 2020 16:23:45 +0800 Subject: [PATCH 1/2] Handle GUID type before Change Type. --- .../Volo/Abp/EntityFrameworkCore/AbpDbContext.cs | 10 +++++++++- .../Volo/Abp/Data/HasExtraPropertiesExtensions.cs | 12 +++++++++--- .../Domain/ExtraProperties_Tests.cs | 2 ++ .../Domain/TestEntityExtensionConfigurator.cs | 5 ++++- .../Volo/Abp/TestApp/TestDataBuilder.cs | 3 ++- .../Testing/HasExtraPropertiesExtensions_Tests.cs | 5 ++++- 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index c82912f0f1..207ab759d0 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; using System.Globalization; using System.Linq; @@ -339,7 +340,14 @@ namespace Volo.Abp.EntityFrameworkCore { if (TypeHelper.IsPrimitiveExtended(entryProperty.Metadata.ClrType, includeEnums: true)) { - entryProperty.CurrentValue = Convert.ChangeType(entityProperty, entryProperty.Metadata.ClrType, CultureInfo.InvariantCulture); + if (entryProperty.Metadata.ClrType == typeof(Guid)) + { + entryProperty.CurrentValue = TypeDescriptor.GetConverter(entryProperty.Metadata.ClrType).ConvertFromInvariantString(entityProperty.ToString()); + } + else + { + entryProperty.CurrentValue = Convert.ChangeType(entityProperty, entryProperty.Metadata.ClrType, CultureInfo.InvariantCulture); + } } } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs index 6abb350328..a7cc08a6bd 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using Volo.Abp.DynamicProxy; using Volo.Abp.ObjectExtending; @@ -32,6 +33,11 @@ namespace Volo.Abp.Data if (TypeHelper.IsPrimitiveExtended(typeof(TProperty), includeEnums: true)) { + if (typeof(TProperty) == typeof(Guid)) + { + return (TProperty)TypeDescriptor.GetConverter(typeof(TProperty)).ConvertFromInvariantString(value.ToString()); + } + return (TProperty)Convert.ChangeType(value, typeof(TProperty), CultureInfo.InvariantCulture); } @@ -39,8 +45,8 @@ namespace Volo.Abp.Data } public static TSource SetProperty( - this TSource source, - string name, + this TSource source, + string name, object value, bool validate = true) where TSource : IHasExtraProperties @@ -96,4 +102,4 @@ namespace Volo.Abp.Data ((IHasExtraProperties) source).SetDefaultsForExtraProperties(objectType); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs index f8edd1f5f1..ce2bbe0590 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs @@ -29,12 +29,14 @@ namespace Volo.Abp.EntityFrameworkCore.Domain london.ExtraProperties["PhoneCode"] = 123456; london.ExtraProperties["Rank"] = "88"; london.ExtraProperties["ZipCode"] = null; + london.ExtraProperties["Guid"] = "a7ae2efe-d8d6-466b-92e3-da14aa6e1c5b"; await CityRepository.UpdateAsync(london); var london2 = await CityRepository.FindByNameAsync("London"); london2.GetProperty("PhoneCode").ShouldBe("123456"); london2.GetProperty("Rank").ShouldBe(88); london2.GetProperty("ZipCode").ShouldBe(null); + london2.GetProperty("Guid").ShouldBe(new Guid("a7ae2efe-d8d6-466b-92e3-da14aa6e1c5b")); } diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs index dd723ffb55..8f81771bc7 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs @@ -1,4 +1,5 @@ -using Volo.Abp.ObjectExtending; +using System; +using Volo.Abp.ObjectExtending; using Volo.Abp.TestApp.Domain; using Volo.Abp.Threading; @@ -24,6 +25,8 @@ namespace Volo.Abp.EntityFrameworkCore.Domain "ZipCode" ).MapEfCoreProperty( "Rank" + ).MapEfCoreProperty( + "Guid" ); }); } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs index 4b5f390d85..36874abad1 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestDataBuilder.cs @@ -52,7 +52,8 @@ namespace Volo.Abp.TestApp { { "Population", 10_470_000 }, { "PhoneCode", "42" }, - { "ZipCode", "1000" } + { "ZipCode", "1000" }, + { "Guid", "a5ed8170-30b9-4580-a395-a3c2dbc031ee" } } }); await _cityRepository.InsertAsync(istanbul); diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs index 918e96581b..fba68cc23b 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs @@ -32,6 +32,9 @@ namespace Volo.Abp.TestApp.Testing city.HasProperty("IsHot").ShouldBeFalse(); city.GetProperty("IsHot").ShouldBeFalse(); city.GetProperty("IsHot", true).ShouldBeTrue(); + + city.SetProperty("Guid", "2260AFEC-BBFD-42D4-A91A-DCB11E09B17F"); + city.GetProperty("Guid").ShouldBe(new Guid("2260AFEC-BBFD-42D4-A91A-DCB11E09B17F")); } } -} \ No newline at end of file +} From 356dcb6648e628f3ff2ab9d5b44dc4adabf34436 Mon Sep 17 00:00:00 2001 From: maliming <6908465+maliming@users.noreply.github.com> Date: Fri, 18 Sep 2020 16:14:27 +0800 Subject: [PATCH 2/2] Handle nullable type. --- .../Volo/Abp/EntityFrameworkCore/AbpDbContext.cs | 13 ++++++++++--- .../Volo/Abp/Data/HasExtraPropertiesExtensions.cs | 13 ++++++++++--- .../Domain/ExtraProperties_Tests.cs | 3 ++- .../Domain/TestEntityExtensionConfigurator.cs | 2 ++ .../Testing/HasExtraPropertiesExtensions_Tests.cs | 9 +++++++++ 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 207ab759d0..9a61e7f8e3 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -23,6 +23,7 @@ using Volo.Abp.EntityFrameworkCore.EntityHistory; using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.ValueConverters; using Volo.Abp.Guids; +using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectExtending; using Volo.Abp.Reflection; @@ -340,13 +341,19 @@ namespace Volo.Abp.EntityFrameworkCore { if (TypeHelper.IsPrimitiveExtended(entryProperty.Metadata.ClrType, includeEnums: true)) { - if (entryProperty.Metadata.ClrType == typeof(Guid)) + var conversionType = entryProperty.Metadata.ClrType; + if (TypeHelper.IsNullable(conversionType)) { - entryProperty.CurrentValue = TypeDescriptor.GetConverter(entryProperty.Metadata.ClrType).ConvertFromInvariantString(entityProperty.ToString()); + conversionType = conversionType.GetFirstGenericArgumentIfNullable(); + } + + if (conversionType == typeof(Guid)) + { + entryProperty.CurrentValue = TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(entityProperty.ToString()); } else { - entryProperty.CurrentValue = Convert.ChangeType(entityProperty, entryProperty.Metadata.ClrType, CultureInfo.InvariantCulture); + entryProperty.CurrentValue = Convert.ChangeType(entityProperty, conversionType, CultureInfo.InvariantCulture); } } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs index a7cc08a6bd..22b135c3d0 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using Volo.Abp.DynamicProxy; +using Volo.Abp.Localization; using Volo.Abp.ObjectExtending; using Volo.Abp.Reflection; @@ -33,12 +34,18 @@ namespace Volo.Abp.Data if (TypeHelper.IsPrimitiveExtended(typeof(TProperty), includeEnums: true)) { - if (typeof(TProperty) == typeof(Guid)) + var conversionType = typeof(TProperty); + if (TypeHelper.IsNullable(conversionType)) { - return (TProperty)TypeDescriptor.GetConverter(typeof(TProperty)).ConvertFromInvariantString(value.ToString()); + conversionType = conversionType.GetFirstGenericArgumentIfNullable(); } - return (TProperty)Convert.ChangeType(value, typeof(TProperty), CultureInfo.InvariantCulture); + if (conversionType == typeof(Guid)) + { + return (TProperty)TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString()); + } + + return (TProperty)Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); } throw new AbpException("GetProperty does not support non-primitive types. Use non-generic GetProperty method and handle type casting manually."); diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs index ce2bbe0590..f94f16c390 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs @@ -29,6 +29,7 @@ namespace Volo.Abp.EntityFrameworkCore.Domain london.ExtraProperties["PhoneCode"] = 123456; london.ExtraProperties["Rank"] = "88"; london.ExtraProperties["ZipCode"] = null; + london.ExtraProperties["Established"] = DateTime.MinValue; london.ExtraProperties["Guid"] = "a7ae2efe-d8d6-466b-92e3-da14aa6e1c5b"; await CityRepository.UpdateAsync(london); @@ -36,10 +37,10 @@ namespace Volo.Abp.EntityFrameworkCore.Domain london2.GetProperty("PhoneCode").ShouldBe("123456"); london2.GetProperty("Rank").ShouldBe(88); london2.GetProperty("ZipCode").ShouldBe(null); + london2.GetProperty("Established").ShouldBe(DateTime.MinValue); london2.GetProperty("Guid").ShouldBe(new Guid("a7ae2efe-d8d6-466b-92e3-da14aa6e1c5b")); } - [Fact] public async Task An_Extra_Property_Configured_As_Extension2() { diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs index 8f81771bc7..15868e3966 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs @@ -25,6 +25,8 @@ namespace Volo.Abp.EntityFrameworkCore.Domain "ZipCode" ).MapEfCoreProperty( "Rank" + ).MapEfCoreProperty( + "Established" ).MapEfCoreProperty( "Guid" ); diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs index fba68cc23b..633c0a0257 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HasExtraPropertiesExtensions_Tests.cs @@ -33,8 +33,17 @@ namespace Volo.Abp.TestApp.Testing city.GetProperty("IsHot").ShouldBeFalse(); city.GetProperty("IsHot", true).ShouldBeTrue(); + city.GetProperty("IsHot?").ShouldBeNull(); + city.GetProperty("IsHot?", true).Value.ShouldBeTrue(); + city.SetProperty("Guid", "2260AFEC-BBFD-42D4-A91A-DCB11E09B17F"); city.GetProperty("Guid").ShouldBe(new Guid("2260AFEC-BBFD-42D4-A91A-DCB11E09B17F")); + + city.SetProperty("Guid?", "2260AFEC-BBFD-42D4-A91A-DCB11E09B17F"); + city.GetProperty("Guid?").ShouldBe(new Guid("2260AFEC-BBFD-42D4-A91A-DCB11E09B17F")); + + city.SetProperty("DateTime?", DateTime.MinValue); + city.GetProperty("DateTime?").ShouldBe(DateTime.MinValue); } } }