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 Flatten
} }
public enum SelectNullHandling
{
LeaveAsIs,
Handle
}
internal static class Constants internal static class Constants
{ {
internal static readonly MethodInfo GroupByMethod = typeof(Queryable).GetMethods().First(t => t.Name == "GroupBy"); 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="param">Expression.Parameter(typeOfClassOrInterface)</param>
/// <param name="path">the path you wish to resolve example Contact.Profile.FirstName</param> /// <param name="path">the path you wish to resolve example Contact.Profile.FirstName</param>
/// <returns></returns> /// <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); var expressionParser = new ExpressionParser(param, path);
if (parts.Any(t => t.IsGenericEnumerable())) expressionParser.Parse();
throw new Exception("this method does not support collection handling");
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) 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 ParameterExpression Parameter { get; protected set; }
public string Path { get; set; } public string Path { get; set; }
public List<ExpressionParserPiece> Pieces { get; set; } = new List<ExpressionParserPiece>(); 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) public ExpressionParser(Type type, string path) : this(Expression.Parameter(type), path)
{ {

View File

@ -14,11 +14,6 @@ namespace PoweredSoft.DynamicLinq.Parser
#if DEBUG #if DEBUG
public override string ToString() => $"{Parameter?.ToString()} is {Parameter?.Type} | {(Pieces == null ? "" : string.Join(" -> ", Pieces.Select(t2 => t2.ToString())))}"; 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 #endif
} }
} }

View File

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