diff --git a/PoweredSoft.DynamicLinq.Test/GroupingTests.cs b/PoweredSoft.DynamicLinq.Test/GroupingTests.cs index ef9df7a..0fa6ef4 100644 --- a/PoweredSoft.DynamicLinq.Test/GroupingTests.cs +++ b/PoweredSoft.DynamicLinq.Test/GroupingTests.cs @@ -14,31 +14,51 @@ namespace PoweredSoft.DynamicLinq.Test public void WantedSyntax() { var regularSyntax = TestData.Sales - .GroupBy(t => t.ClientId) - .Select(t => new - { - TheClientId = t.Key, - Count = t.Count(), - CountClientId = t.Count(t2 => t2.ClientId > 1), - LongCount = t.LongCount(), - NetSales = t.Sum(t2 => t2.NetSales), - TaxAverage = t.Average(t2 => t2.Tax), - Sales = t.ToList() - }); - /* + .GroupBy(t => t.ClientId); + var dynamicSyntax = TestData.Sales - .GroupBy("ClientId") - .Select(t => + .AsQueryable() + .GroupBy("ClientId"); + + /* + + var regularSyntax2 = TestData.Sales + .GroupBy(t => new { - t.PropertyFromKey("TheClientId", "ClientId"); - t.Count("Count"); - // don't have to implement right away. - t.Count("CountClientId", "ClientId", ConditionOperators.GreaterThan, 1); - t.LongCount("LongCount"); - t.Sum("NetSales"); - t.Average("TaxAverage", "Tax"); - t.ToList("Sales"); - });*/ + t.ClientId, + t.NetSales + }); + + var dynamicSyntax2 = TestData.Sales + .AsQueryable() + .GroupBy("ClientId", "NetSales");*/ + + /* + .Select(t => new + { + TheClientId = t.Key, + Count = t.Count(), + CountClientId = t.Count(t2 => t2.ClientId > 1), + LongCount = t.LongCount(), + NetSales = t.Sum(t2 => t2.NetSales), + TaxAverage = t.Average(t2 => t2.Tax), + Sales = t.ToList() + });*/ + + + + /* + .Select(t => + { + t.PropertyFromKey("TheClientId", "ClientId"); + t.Count("Count"); + // don't have to implement right away. + t.Count("CountClientId", "ClientId", ConditionOperators.GreaterThan, 1); + t.LongCount("LongCount"); + t.Sum("NetSales"); + t.Average("TaxAverage", "Tax"); + t.ToList("Sales"); + });*/ } } } diff --git a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj index efadda6..209a992 100644 --- a/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj +++ b/PoweredSoft.DynamicLinq.Test/PoweredSoft.DynamicLinq.Test.csproj @@ -62,6 +62,7 @@ + diff --git a/PoweredSoft.DynamicLinq/Constants.cs b/PoweredSoft.DynamicLinq/Constants.cs index f4f8eb6..41f5e0b 100644 --- a/PoweredSoft.DynamicLinq/Constants.cs +++ b/PoweredSoft.DynamicLinq/Constants.cs @@ -43,6 +43,7 @@ namespace PoweredSoft.DynamicLinq internal static class Constants { + internal static readonly MethodInfo GroupByMethod = typeof(Queryable).GetMethods().First(t => t.Name == "GroupBy"); internal static readonly MethodInfo StringEqualWithComparisation = typeof(string).GetMethod("Equals", new Type[] { typeof(string), typeof(StringComparison) }); internal static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains"); internal static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }); diff --git a/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs b/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs index 5e7058a..72907e1 100644 --- a/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs +++ b/PoweredSoft.DynamicLinq/Extensions/QueryableExtensions.cs @@ -69,5 +69,18 @@ namespace PoweredSoft.DynamicLinq var ret = qb.Build(); return ret; } + + public static IQueryable GroupBy(this IQueryable query, string path) + where T : class + { + var ret = query.GroupBy(typeof(T), path); + return ret as IQueryable; + } + + public static IQueryable GroupBy(this IQueryable query, Type type, string path) + { + var ret = QueryableHelpers.GroupBy(query, type, path); + return ret; + } } } diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs index 455766e..09ce236 100644 --- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs @@ -6,6 +6,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; +using System.Reflection.Emit; namespace PoweredSoft.DynamicLinq.Helpers { @@ -76,6 +77,42 @@ namespace PoweredSoft.DynamicLinq.Helpers return ret; } + public static IQueryable GroupBy(IQueryable query, Type type, string path) + { + var parameter = Expression.Parameter(type, "t"); + var field = QueryableHelpers.ResolvePathForExpression(parameter, path); + var lambda = Expression.Lambda(field, parameter); + var genericMethod = Constants.GroupByMethod.MakeGenericMethod(type, field.Type); + var groupByEpression = Expression.Call(genericMethod, query.Expression, lambda); + var result = query.Provider.CreateQuery(groupByEpression); + return result; + } + + private static IQueryable GroupByAnonymousObject(IQueryable query, Type type, ParameterExpression parameter, List fields) + { + throw new NotSupportedException(); + /* + var dynamicAssemblyName = new AssemblyName("PoweredSoft.DynamicLinq.DynamicTypes"); + var dynamicAssembly = AssemblyBuilder.DefineDynamicAssembly(dynamicAssemblyName, System.Reflection.Emit.AssemblyBuilderAccess.Run); + System.Reflection.Emit.ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("TempAssembly"); + + TypeBuilder dynamicAnonymousType = dynamicModule.DefineType("AnonymousType", TypeAttributes.Public); + + int i = 0; + fields.ForEach(field => + { + var fieldName = $"A_{++i}"; // tODO + dynamicAnonymousType.DefineField(fieldName. + }); + + dynamicAnonymousType.DefineField(, typeof(TFieldA), FieldAttributes.Public); + dynamicAnonymousType.DefineField(fieldNameB, typeof(TFieldB), FieldAttributes.Public); + + return dynamicAnonymousType.CreateType(); + + throw new NotImplementedException(); */ + } + /// /// Returns the right expression for a path supplied. ///