From b62479733060cebd604ebd372dd91dc1c2762cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leb=C3=A9e?= Date: Sun, 11 Mar 2018 21:54:13 -0500 Subject: [PATCH] create anonymous type and group by it. :) --- .../Helpers/QueryableHelpers.cs | 6 +++-- .../Helpers/TypeHelpers.cs | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs index 57fac38..698e296 100644 --- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs @@ -99,8 +99,10 @@ namespace PoweredSoft.DynamicLinq.Helpers var constructor = anonymousType.GetConstructor(constructorTypes); var newExpression = Expression.New(constructor, partExpressions); var genericMethod = Constants.GroupByMethod.MakeGenericMethod(type, anonymousType); - - return query; + var lambda = Expression.Lambda(newExpression, parameter); + var groupByExpression = Expression.Call(genericMethod, query.Expression, lambda); + var result = query.Provider.CreateQuery(groupByExpression); + return result; } public static IQueryable GroupBy(IQueryable query, Type type, string path) diff --git a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs index 2a7bb2a..334f602 100644 --- a/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/TypeHelpers.cs @@ -50,10 +50,34 @@ namespace PoweredSoft.DynamicLinq.Helpers { CreatePropertyOnType(dynamicType, field.name, field.type); }); + CreateConstructorWithAllPropsOnType(dynamicType, fields); var ret = dynamicType.CreateTypeInfo(); return ret; } + 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()); + var parameters = fields + .Select((field, i) => + { + return ctor.DefineParameter(i++, ParameterAttributes.None, $"{field.name}_1"); + }) + .ToList(); + + var emitter = ctor.GetILGenerator(); + emitter.Emit(OpCodes.Nop); + + // Load `this` and call base constructor with arguments + emitter.Emit(OpCodes.Ldarg_0); + for (var i = 1; i <= parameters.Count; ++i) + { + emitter.Emit(OpCodes.Ldarg, i); + } + emitter.Emit(OpCodes.Call, ctor); + emitter.Emit(OpCodes.Ret); + } + internal static void CreatePropertyOnType(TypeBuilder typeBuilder, string propertyName, Type propertyType) { // Generate a property called "Name"