works well :)

This commit is contained in:
David Lebée 2018-04-11 22:18:10 -05:00
parent 20da18bbdf
commit 271fca885f
6 changed files with 20 additions and 76 deletions

View File

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

View File

@ -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<ExpressionPathPart> Split(ParameterExpression param, string path)
{
var ret = new List<ExpressionPathPart>();
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();
}
}

View File

@ -302,13 +302,17 @@ namespace PoweredSoft.DynamicLinq.Helpers
/// <param name="param">Expression.Parameter(typeOfClassOrInterface)</param>
/// <param name="path">the path you wish to resolve example Contact.Profile.FirstName</param>
/// <returns></returns>
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)

View File

@ -11,6 +11,7 @@ namespace PoweredSoft.DynamicLinq.Parser
public ParameterExpression Parameter { get; protected set; }
public string Path { get; set; }
public List<ExpressionParserPiece> Pieces { get; set; } = new List<ExpressionParserPiece>();
public bool IsParsed => Pieces?.Count > 0;
public ExpressionParser(Type type, string path) : this(Expression.Parameter(type), path)
{

View File

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

View File

@ -37,6 +37,7 @@ namespace PoweredSoft.DynamicLinq.Resolver
Result = null;
// parse the expression.
if (!Parser.IsParsed)
Parser.Parse();
// group the piece by common parameters
@ -170,5 +171,13 @@ namespace PoweredSoft.DynamicLinq.Resolver
return parentExpression;
}
public Expression GetResultBodyExpression()
{
if (Result == null)
return Result;
return ((LambdaExpression)Result).Body;
}
}
}