create anonymous type and group by it. :)

This commit is contained in:
David Lebée 2018-03-11 21:54:13 -05:00
parent 515d0bee37
commit b624797330
2 changed files with 28 additions and 2 deletions

View File

@ -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)

View File

@ -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"