works well :)
This commit is contained in:
parent
20da18bbdf
commit
271fca885f
@ -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");
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user