From 271fca885f8732dde145ae6c317e5578d2b6b8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leb=C3=A9e?= Date: Wed, 11 Apr 2018 22:18:10 -0500 Subject: [PATCH] works well :) --- PoweredSoft.DynamicLinq/Constants.cs | 6 -- PoweredSoft.DynamicLinq/ExpressionPathPart.cs | 59 ------------------- .../Helpers/QueryableHelpers.cs | 14 +++-- .../Parser/ExpressionParser.cs | 1 + .../Parser/ExpressionParserPieceGroup.cs | 5 -- .../Resolver/PathExpressionResolver.cs | 11 +++- 6 files changed, 20 insertions(+), 76 deletions(-) delete mode 100644 PoweredSoft.DynamicLinq/ExpressionPathPart.cs diff --git a/PoweredSoft.DynamicLinq/Constants.cs b/PoweredSoft.DynamicLinq/Constants.cs index d8da956..e023863 100644 --- a/PoweredSoft.DynamicLinq/Constants.cs +++ b/PoweredSoft.DynamicLinq/Constants.cs @@ -59,12 +59,6 @@ namespace PoweredSoft.DynamicLinq Flatten } - public enum SelectNullHandling - { - LeaveAsIs, - Handle - } - internal static class Constants { internal static readonly MethodInfo GroupByMethod = typeof(Queryable).GetMethods().First(t => t.Name == "GroupBy"); diff --git a/PoweredSoft.DynamicLinq/ExpressionPathPart.cs b/PoweredSoft.DynamicLinq/ExpressionPathPart.cs deleted file mode 100644 index b3396bd..0000000 --- a/PoweredSoft.DynamicLinq/ExpressionPathPart.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace PoweredSoft.DynamicLinq.Helpers -{ - public class ExpressionPathPart - { - public Expression ParentExpression { get; set; } - public ParameterExpression ParameterExpression { get; set; } - public Expression PartExpression { get; set; } - - public bool IsNullable() => TypeHelpers.IsNullable(PartExpression.Type); - - public bool IsGenericEnumerable() => QueryableHelpers.IsGenericEnumerable(PartExpression); - public Type GenericEnumerableType() => PartExpression.Type.GenericTypeArguments.First(); - public bool IsCallingMethod() => PartExpression is MethodCallExpression; - public Type GetToListType() => IsGenericEnumerable() ? GenericEnumerableType() : PartExpression.Type; - public bool IsParentGenericEnumerable() => QueryableHelpers.IsGenericEnumerable(ParentExpression); - - public static List Split(ParameterExpression param, string path) - { - var ret = new List(); - - var parts = path.Split('.').ToList(); - Expression parent = param; - parts.ForEach(part => - { - var p = new ExpressionPathPart(); - p.PartExpression = Expression.PropertyOrField(parent, part); - p.ParentExpression = parent; - p.ParameterExpression = param; - ret.Add(p); - - if (p.IsGenericEnumerable()) - { - param = Expression.Parameter(p.GenericEnumerableType()); - parent = param; - } - else - { - parent = p.PartExpression; - } - }); - - return ret; - } - - public LambdaExpression GetLambdaExpression() - { - var lambda = Expression.Lambda(PartExpression, ParameterExpression); - return lambda; - } - - public Type ParentGenericEnumerableType() => ParentExpression.Type.GenericTypeArguments.First(); - - } -} diff --git a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs index feb985d..8fd42f0 100644 --- a/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs +++ b/PoweredSoft.DynamicLinq/Helpers/QueryableHelpers.cs @@ -302,13 +302,17 @@ namespace PoweredSoft.DynamicLinq.Helpers /// Expression.Parameter(typeOfClassOrInterface) /// the path you wish to resolve example Contact.Profile.FirstName /// - public static Expression ResolvePathForExpression(ParameterExpression param, string path) + public static Expression ResolvePathForExpression(ParameterExpression param, string path, bool throwIfHasEnumerable = true) { - var parts = ExpressionPathPart.Split(param, path); - if (parts.Any(t => t.IsGenericEnumerable())) - throw new Exception("this method does not support collection handling"); + var expressionParser = new ExpressionParser(param, path); + expressionParser.Parse(); - return parts.Last().PartExpression; + if (throwIfHasEnumerable && expressionParser.Pieces.Any(t2 => t2.IsGenericEnumerable)) + throw new Exception("Path contains an enumerable, and this feature does not support it."); + + var expressionResolver = new PathExpressionResolver(expressionParser); + expressionResolver.Resolve(); + return expressionResolver.GetResultBodyExpression(); } public static ConstantExpression GetConstantSameAsLeftOperator(Expression member, object value) diff --git a/PoweredSoft.DynamicLinq/Parser/ExpressionParser.cs b/PoweredSoft.DynamicLinq/Parser/ExpressionParser.cs index 2e2a8e9..721d459 100644 --- a/PoweredSoft.DynamicLinq/Parser/ExpressionParser.cs +++ b/PoweredSoft.DynamicLinq/Parser/ExpressionParser.cs @@ -11,6 +11,7 @@ namespace PoweredSoft.DynamicLinq.Parser public ParameterExpression Parameter { get; protected set; } public string Path { get; set; } public List Pieces { get; set; } = new List(); + public bool IsParsed => Pieces?.Count > 0; public ExpressionParser(Type type, string path) : this(Expression.Parameter(type), path) { diff --git a/PoweredSoft.DynamicLinq/Parser/ExpressionParserPieceGroup.cs b/PoweredSoft.DynamicLinq/Parser/ExpressionParserPieceGroup.cs index 79d1980..7673507 100644 --- a/PoweredSoft.DynamicLinq/Parser/ExpressionParserPieceGroup.cs +++ b/PoweredSoft.DynamicLinq/Parser/ExpressionParserPieceGroup.cs @@ -14,11 +14,6 @@ namespace PoweredSoft.DynamicLinq.Parser #if DEBUG public override string ToString() => $"{Parameter?.ToString()} is {Parameter?.Type} | {(Pieces == null ? "" : string.Join(" -> ", Pieces.Select(t2 => t2.ToString())))}"; - - public object CompileSimpleExpress(SelectNullHandling nullHandling) - { - throw new NotImplementedException(); - } #endif } } diff --git a/PoweredSoft.DynamicLinq/Resolver/PathExpressionResolver.cs b/PoweredSoft.DynamicLinq/Resolver/PathExpressionResolver.cs index f86cc0f..a59b425 100644 --- a/PoweredSoft.DynamicLinq/Resolver/PathExpressionResolver.cs +++ b/PoweredSoft.DynamicLinq/Resolver/PathExpressionResolver.cs @@ -37,7 +37,8 @@ namespace PoweredSoft.DynamicLinq.Resolver Result = null; // parse the expression. - Parser.Parse(); + if (!Parser.IsParsed) + Parser.Parse(); // group the piece by common parameters var groups = Parser.GroupBySharedParameters(); @@ -170,5 +171,13 @@ namespace PoweredSoft.DynamicLinq.Resolver return parentExpression; } + + public Expression GetResultBodyExpression() + { + if (Result == null) + return Result; + + return ((LambdaExpression)Result).Body; + } } }