From 165cc15d0a37f629c5fe03bf34c0e341a5c4dc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leb=C3=A9e?= Date: Mon, 12 Mar 2018 17:23:02 -0500 Subject: [PATCH] Allow possibility of specifying the type to group with :) --- PoweredSoft.DynamicLinq.Test/GroupingTests.cs | 11 +++++++++++ .../Extensions/QueryableExtensions.cs | 2 +- PoweredSoft.DynamicLinq/Fluent/Group/GroupBuilder.cs | 7 +++++++ PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs | 4 ++-- PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs | 10 +++++++--- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/PoweredSoft.DynamicLinq.Test/GroupingTests.cs b/PoweredSoft.DynamicLinq.Test/GroupingTests.cs index 498d13e..fbfd06f 100644 --- a/PoweredSoft.DynamicLinq.Test/GroupingTests.cs +++ b/PoweredSoft.DynamicLinq.Test/GroupingTests.cs @@ -8,6 +8,12 @@ using PoweredSoft.DynamicLinq; namespace PoweredSoft.DynamicLinq.Test { + internal class TestStructure + { + public long ClientId { get; set; } + public decimal B { get; set; } + } + [TestClass] public class GroupingTests { @@ -34,6 +40,11 @@ namespace PoweredSoft.DynamicLinq.Test .AsQueryable() .GroupBy(t => t.Path("ClientId").Path("NetSales", "B")); + var dynamicSyntax3 = TestData.Sales + .AsQueryable() + .GroupBy(t => t.UseType(typeof(TestStructure)).Path("ClientId").Path("NetSales", "B")); + + /* .Select(t => new { diff --git a/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs b/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs index 8297368..62d4985 100644 --- a/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs +++ b/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs @@ -86,7 +86,7 @@ namespace PoweredSoft.DynamicLinq if (groupBuilder.Empty) throw new Exception("No group specified, please specify at least one group"); - return QueryableHelpers.GroupBy(query, type, groupBuilder.Parts); + return QueryableHelpers.GroupBy(query, type, groupBuilder.Parts, groupBuilder.Type); } } } diff --git a/PoweredSoft.DynamicLinq/Fluent/Group/GroupBuilder.cs b/PoweredSoft.DynamicLinq/Fluent/Group/GroupBuilder.cs index ebfa1e1..deaefd8 100644 --- a/PoweredSoft.DynamicLinq/Fluent/Group/GroupBuilder.cs +++ b/PoweredSoft.DynamicLinq/Fluent/Group/GroupBuilder.cs @@ -8,6 +8,7 @@ namespace PoweredSoft.DynamicLinq.Fluent public class GroupBuilder { public List<(string path, string propertyName)> Parts { get; set; } = new List<(string path, string propertyName)>(); + public Type Type { get; set; } public bool Empty => !Parts.Any(); public GroupBuilder Path(string path, string propertyName = null) @@ -30,5 +31,11 @@ namespace PoweredSoft.DynamicLinq.Fluent Parts.Add((path, propertyName)); return this; } + + public GroupBuilder UseType(Type type) + { + Type = type; + return this; + } } } diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs index 536fa3b..9bffde4 100644 --- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs @@ -77,7 +77,7 @@ namespace PoweredSoft.DynamicLinq.Helpers return ret; } - public static IQueryable GroupBy(IQueryable query, Type type, List<(string path, string propertyName)> parts) + public static IQueryable GroupBy(IQueryable query, Type type, List<(string path, string propertyName)> parts, Type groupToType = null) { // EXPRESSION var parameter = Expression.Parameter(type, "t"); @@ -93,7 +93,7 @@ namespace PoweredSoft.DynamicLinq.Helpers partExpressions.Add((partExpression, part.propertyName)); }); - var anonymousType = TypeHelpers.CreateSimpleAnonymousType(fields); + var anonymousType = groupToType ?? TypeHelpers.CreateSimpleAnonymousType(fields); /* diff --git a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs index 1ba9ce1..1e6a78b 100644 --- a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs @@ -36,8 +36,7 @@ namespace PoweredSoft.DynamicLinq.Helpers } /// - /// Use this to create anonymous type concstructor for LINQ queries :) - /// https://stackoverflow.com/questions/6879279/using-typebuilder-to-create-a-pass-through-constructor-for-the-base-class + /// Use this to create anonymous type /// /// /// @@ -50,11 +49,16 @@ namespace PoweredSoft.DynamicLinq.Helpers { CreatePropertyOnType(dynamicType, field.name, field.type); }); + // not needed at the end. // CreateConstructorWithAllPropsOnType(dynamicType, fields); var ret = dynamicType.CreateTypeInfo(); return ret; } + /* + * concstructor + * https://stackoverflow.com/questions/6879279/using-typebuilder-to-create-a-pass-through-constructor-for-the-base-class + * works but wasn't needed at the end. private static void CreateConstructorWithAllPropsOnType(TypeBuilder dynamicType, List<(Type type, string name)> fields) { var ctor = dynamicType.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, fields.Select(t => t.type).ToArray()); @@ -76,7 +80,7 @@ namespace PoweredSoft.DynamicLinq.Helpers } emitter.Emit(OpCodes.Call, ctor); emitter.Emit(OpCodes.Ret); - } + }*/ internal static void CreatePropertyOnType(TypeBuilder typeBuilder, string propertyName, Type propertyType) {