diff --git a/PoweredSoft.Conversion/Convert.cs b/PoweredSoft.Conversion/Convert.cs new file mode 100644 index 0000000..b84630c --- /dev/null +++ b/PoweredSoft.Conversion/Convert.cs @@ -0,0 +1,58 @@ +using PoweredSoft.Types.Converters; +using PoweredSoft.Types.Interface; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PoweredSoft.Types +{ + public static class Converter + { + public static List Converters { get; internal set; } = new List + { + new StringToDateConverter(), + new StringToGuidConverter() + }; + + public static void RegisterConverter(ITypeConverter converter) + { + lock (Converters) + { + Converters.Add(converter); + } + } + + public static void ReplaceConverter(ITypeConverter converter, Type source, Type destination) + { + lock (Converters) + { + Converters.RemoveAll(t => t.CanConvert(source, destination)); + Converters.Add(converter); + } + } + + public static object To(this object source, Type type) + { + object ret = null; + + // safe if null. + if (source == null) + return ret; + + // establish final type. + var notNullType = Nullable.GetUnderlyingType(type); + var finalType = notNullType ?? type; + var converter = Converters.FirstOrDefault(t => t.CanConvert(source.GetType(), finalType)); + if (converter != null) + ret = converter.Convert(source, finalType); + else + ret = Convert.ChangeType(source, finalType); + + if (notNullType != null) + ret = Activator.CreateInstance(type, new object[] { ret }); + + return ret; + } + } +} diff --git a/PoweredSoft.Conversion/Converters/StringToDateConverter.cs b/PoweredSoft.Conversion/Converters/StringToDateConverter.cs new file mode 100644 index 0000000..06b4fb8 --- /dev/null +++ b/PoweredSoft.Conversion/Converters/StringToDateConverter.cs @@ -0,0 +1,13 @@ +using PoweredSoft.Types.Interface; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.Types.Converters +{ + public class StringToDateConverter : ITypeConverter + { + public bool CanConvert(Type source, Type destination) => source == typeof(string) && destination == typeof(DateTime); + public object Convert(object source, Type destination) => DateTime.Parse((string)source); + } +} diff --git a/PoweredSoft.Conversion/Converters/StringToGuidConverter.cs b/PoweredSoft.Conversion/Converters/StringToGuidConverter.cs new file mode 100644 index 0000000..ecd260d --- /dev/null +++ b/PoweredSoft.Conversion/Converters/StringToGuidConverter.cs @@ -0,0 +1,13 @@ +using PoweredSoft.Types.Interface; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.Types.Converters +{ + public class StringToGuidConverter : ITypeConverter + { + public bool CanConvert(Type source, Type destination) => source == typeof(string) && destination == typeof(Guid); + public object Convert(object source, Type destination) => Guid.Parse((string)source); + } +} diff --git a/PoweredSoft.Conversion/Interface/ITypeConverter.cs b/PoweredSoft.Conversion/Interface/ITypeConverter.cs new file mode 100644 index 0000000..c9a8b7a --- /dev/null +++ b/PoweredSoft.Conversion/Interface/ITypeConverter.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace PoweredSoft.Types.Interface +{ + public interface ITypeConverter + { + bool CanConvert(Type source, Type destination); + object Convert(object source, Type destination); + } +} diff --git a/PoweredSoft.Conversion/PoweredSoft.Types.csproj b/PoweredSoft.Conversion/PoweredSoft.Types.csproj new file mode 100644 index 0000000..9f5c4f4 --- /dev/null +++ b/PoweredSoft.Conversion/PoweredSoft.Types.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/PoweredSoft.DynamicLinq.Dal/BlogContext.cs b/PoweredSoft.DynamicLinq.Dal/BlogContext.cs index 6090b12..c6a1ae1 100644 --- a/PoweredSoft.DynamicLinq.Dal/BlogContext.cs +++ b/PoweredSoft.DynamicLinq.Dal/BlogContext.cs @@ -37,6 +37,8 @@ namespace PoweredSoft.DynamicLinq.Dal modelBuilder.Configurations.Add(new CommentConfiguration()); modelBuilder.Configurations.Add(new PostConfiguration()); modelBuilder.Configurations.Add(new WebsiteConfiguration()); + modelBuilder.Configurations.Add(new CommentLikeConfiguration()); + modelBuilder.Configurations.Add(new UniqueConfiguration()); } } } diff --git a/PoweredSoft.DynamicLinq.Dal/Configurations/Configurations.cs b/PoweredSoft.DynamicLinq.Dal/Configurations/Configurations.cs index 6158ab6..903254f 100644 --- a/PoweredSoft.DynamicLinq.Dal/Configurations/Configurations.cs +++ b/PoweredSoft.DynamicLinq.Dal/Configurations/Configurations.cs @@ -9,6 +9,23 @@ using System.Threading.Tasks; namespace PoweredSoft.DynamicLinq.Dal.Configurations { + public class UniqueConfiguration : EntityTypeConfiguration + { + public UniqueConfiguration() : this("dbo") + { + + } + + public UniqueConfiguration(string schema) + { + ToTable("Unique", schema); + HasKey(t => t.Id); + Property(t => t.Id).HasColumnName("Id").HasColumnType("bigint").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); + Property(t => t.RowNumber).HasColumnType("uniqueidentifier").IsRequired(); + Property(t => t.OtherNullableGuid).HasColumnType("uniqueidentifier"); + } + } + public class AuthorConfiguration : EntityTypeConfiguration { public AuthorConfiguration() : this("dbo") diff --git a/PoweredSoft.DynamicLinq.Dal/Pocos/Uniqe.cs b/PoweredSoft.DynamicLinq.Dal/Pocos/Uniqe.cs new file mode 100644 index 0000000..9f67b98 --- /dev/null +++ b/PoweredSoft.DynamicLinq.Dal/Pocos/Uniqe.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PoweredSoft.DynamicLinq.Dal.Pocos +{ + public class Unique + { + public long Id { get; set; } + public Guid RowNumber { get; set; } + public Guid? OtherNullableGuid { get; set; } + } +} diff --git a/PoweredSoft.DynamicLinq.Dal/PoweredSoft.DynamicLinq.Dal.csproj b/PoweredSoft.DynamicLinq.Dal/PoweredSoft.DynamicLinq.Dal.csproj index 042f01e..edbf788 100644 --- a/PoweredSoft.DynamicLinq.Dal/PoweredSoft.DynamicLinq.Dal.csproj +++ b/PoweredSoft.DynamicLinq.Dal/PoweredSoft.DynamicLinq.Dal.csproj @@ -50,6 +50,7 @@ + diff --git a/PoweredSoft.DynamicLinq.Test/ConstantTests.cs b/PoweredSoft.DynamicLinq.Test/ConstantTests.cs index 2ccf98d..30eed1b 100644 --- a/PoweredSoft.DynamicLinq.Test/ConstantTests.cs +++ b/PoweredSoft.DynamicLinq.Test/ConstantTests.cs @@ -42,6 +42,14 @@ namespace PoweredSoft.DynamicLinq.Test Assert.IsTrue(Posts.AsQueryable().Query(t => t.Equal("Id", 1, QueryConvertStrategy.LeaveAsIs)).Any()); } + [TestMethod] + public void TestGuid() + { + var randomGuidStr = Guid.NewGuid().ToString(); + TestData.Uniques.AsQueryable().Query(t => t.Equal("RowNumber", randomGuidStr)); + TestData.Uniques.AsQueryable().Query(t => t.Equal("OtherNullableGuid", randomGuidStr)); + } + [TestMethod] public void SpecifyType() { diff --git a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj index e41965e..7a858b8 100644 --- a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj +++ b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj @@ -54,6 +54,9 @@ ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + ..\packages\PoweredSoft.Types.1.0.0\lib\netstandard2.0\PoweredSoft.Types.dll + diff --git a/PoweredSoft.DynamicLinq.Test/TestData.cs b/PoweredSoft.DynamicLinq.Test/TestData.cs index 0c6f47d..a8abf5c 100644 --- a/PoweredSoft.DynamicLinq.Test/TestData.cs +++ b/PoweredSoft.DynamicLinq.Test/TestData.cs @@ -34,6 +34,12 @@ namespace PoweredSoft.DynamicLinq.Test internal static class TestData { + static readonly internal List Uniques = new List + { + new Unique { Id = 1, RowNumber = Guid.NewGuid(), OtherNullableGuid = null } , + new Unique { Id = 2, RowNumber = Guid.NewGuid(), OtherNullableGuid = Guid.NewGuid() } + }; + static readonly internal List Persons = new List { new MockPersonObject { FirstName = "David", LastName = "Lebee", Age = 28 }, diff --git a/PoweredSoft.DynamicLinq.Test/packages.config b/PoweredSoft.DynamicLinq.Test/packages.config index f054fb9..1ca1128 100644 --- a/PoweredSoft.DynamicLinq.Test/packages.config +++ b/PoweredSoft.DynamicLinq.Test/packages.config @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/PoweredSoft.DynamicLinq.sln b/PoweredSoft.DynamicLinq.sln index 3c4ae69..d9fe818 100644 --- a/PoweredSoft.DynamicLinq.sln +++ b/PoweredSoft.DynamicLinq.sln @@ -13,6 +13,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.DynamicLinq.Ent EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.DynamicLinq.ConsoleApp", "PoweredSoft.DynamicLinq.ConsoleApp\PoweredSoft.DynamicLinq.ConsoleApp.csproj", "{A166BD89-7BF3-475B-871F-294B8A420D9E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77B4027B-ECB0-4ED1-8646-025AC4146CE2}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs index a53bf21..64d6f96 100644 --- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs @@ -327,17 +327,8 @@ namespace PoweredSoft.DynamicLinq.Helpers if (value == null) return Expression.Constant(null); - // the types. - var valueType = value.GetType(); - var memberType = member.Type; - - // if match. - if (valueType == memberType) - return Expression.Constant(value); - - // attempt a conversion. - object convertedValue = TypeHelpers.ConvertFrom(memberType, value); - return Expression.Constant(convertedValue, memberType); + var convertedValue = PoweredSoft.Types.Converter.To(value, member.Type); + return Expression.Constant(convertedValue, member.Type); } public static ConstantExpression ResolveConstant(Expression member, object value, QueryConvertStrategy convertStrategy) @@ -474,7 +465,7 @@ namespace PoweredSoft.DynamicLinq.Helpers foreach (var o in enumerableValue) { if (convertStrategy == QueryConvertStrategy.ConvertConstantToComparedPropertyOrField) - list.Add(TypeHelpers.ConvertFrom(memberExpression.Type, o)); + list.Add(PoweredSoft.Types.Converter.To(o, memberExpression.Type)); else list.Add(o); } diff --git a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs index f3aae3b..ed3ab0b 100644 --- a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs @@ -24,26 +24,7 @@ namespace PoweredSoft.DynamicLinq.Helpers } - public static object ConvertFrom(Type type, object source) - { - object ret = null; - - // safe if null. - if (source == null) - return ret; - - // not nullable type. - var notNullableType = Nullable.GetUnderlyingType(type); - if (notNullableType == null) - { - ret = Convert.ChangeType(source, type); - return ret; - } - - // the ret. - ret = Convert.ChangeType(source, notNullableType); - return ret; - } + /* /// diff --git a/PoweredSoft.DynamicLinq/PoweredSoft.DynamicLinq.csproj b/PoweredSoft.DynamicLinq/PoweredSoft.DynamicLinq.csproj index 19898a8..c79b829 100644 --- a/PoweredSoft.DynamicLinq/PoweredSoft.DynamicLinq.csproj +++ b/PoweredSoft.DynamicLinq/PoweredSoft.DynamicLinq.csproj @@ -2,7 +2,7 @@ netstandard2.0 - true + false Powered Softwares Inc. David Lebée @@ -22,6 +22,7 @@ +