well advancing but not done yet :)
This commit is contained in:
parent
dcd251f199
commit
14f1091eb8
@ -16,10 +16,58 @@ namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|||||||
{
|
{
|
||||||
var type = typeof(Dal.Pocos.Author);
|
var type = typeof(Dal.Pocos.Author);
|
||||||
var param = Expression.Parameter(type);
|
var param = Expression.Parameter(type);
|
||||||
var path = "Posts.Comments.Id";
|
var parts = ExpressionPathPart.Split(param, "Posts.Comments.Id");
|
||||||
|
|
||||||
var parts = ExpressionPathPart.Break(param, "Posts.Comments.Id");
|
// add the last part.
|
||||||
|
var parent = parts.Last();
|
||||||
|
var toListType = parent.GetToListType();
|
||||||
|
parts.Add(new ExpressionPathPart
|
||||||
|
{
|
||||||
|
ParentExpression = parent.PartExpression,
|
||||||
|
PartExpression = Expression.Call(typeof(Enumerable), "ToList", new[] { toListType }, parent.ParentExpression)
|
||||||
|
});
|
||||||
|
|
||||||
|
var result = CreateSelectExpressionFromParts(parts, SelectCollectionHandling.Flatten, SelectNullHandling.New);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expression CreateSelectExpressionFromParts(List<ExpressionPathPart> parts,
|
||||||
|
SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs,
|
||||||
|
SelectNullHandling nullChecking = SelectNullHandling.LeaveAsIs)
|
||||||
|
{
|
||||||
|
Type nullHandlingRightType = null;
|
||||||
|
Expression nullHandlingNullValue = null;
|
||||||
|
|
||||||
|
if (nullChecking != SelectNullHandling.LeaveAsIs)
|
||||||
|
{
|
||||||
|
nullHandlingRightType = parts.Last().PartExpression.Type;
|
||||||
|
nullHandlingNullValue = nullChecking == SelectNullHandling.Default
|
||||||
|
? Expression.Default(nullHandlingRightType) as Expression
|
||||||
|
: Expression.New(nullHandlingRightType) as Expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reversed :)
|
||||||
|
var reversedCopy = parts.Select(t => t).ToList();
|
||||||
|
reversedCopy.Reverse();
|
||||||
|
|
||||||
|
Expression ret = null;
|
||||||
|
reversedCopy.ForEach(t =>
|
||||||
|
{
|
||||||
|
if (t.IsParentGenericEnumerable())
|
||||||
|
{
|
||||||
|
var lambda = t.GetLambdaExpression();
|
||||||
|
var parentGenericType = t.ParentGenericEnumerableType();
|
||||||
|
if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs || !t.IsGenericEnumerable())
|
||||||
|
ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { parentGenericType, t.PartExpression.Type }, t.ParentExpression, lambda);
|
||||||
|
else
|
||||||
|
ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { parentGenericType, t.GenericEnumerableType() }, t.ParentExpression, lambda);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = t.PartExpression;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,13 @@ namespace PoweredSoft.DynamicLinq
|
|||||||
Flatten
|
Flatten
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SelectNullHandling
|
||||||
|
{
|
||||||
|
LeaveAsIs,
|
||||||
|
Default,
|
||||||
|
New
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
@ -8,13 +8,18 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
public class ExpressionPathPart
|
public class ExpressionPathPart
|
||||||
{
|
{
|
||||||
public Expression ParentExpression { get; set; }
|
public Expression ParentExpression { get; set; }
|
||||||
public Expression Expression { get; set; }
|
public ParameterExpression ParameterExpression { get; set; }
|
||||||
public bool IsNullable() => TypeHelpers.IsNullable(Expression.Type);
|
public Expression PartExpression { get; set; }
|
||||||
public bool IsParentParamaterExpression() => ParentExpression is ParameterExpression;
|
|
||||||
public bool IsGenericEnumerable() => QueryableHelpers.IsGenericEnumerable(Expression);
|
|
||||||
public Type GenericEnumerableType() => Expression.Type.GenericTypeArguments.First();
|
|
||||||
|
|
||||||
public static List<ExpressionPathPart> Break(ParameterExpression param, string path)
|
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 ret = new List<ExpressionPathPart>();
|
||||||
|
|
||||||
@ -23,14 +28,31 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
parts.ForEach(part =>
|
parts.ForEach(part =>
|
||||||
{
|
{
|
||||||
var p = new ExpressionPathPart();
|
var p = new ExpressionPathPart();
|
||||||
p.Expression = Expression.PropertyOrField(parent, part);
|
p.PartExpression = Expression.PropertyOrField(parent, part);
|
||||||
p.ParentExpression = parent;
|
p.ParentExpression = parent;
|
||||||
|
p.ParameterExpression = param;
|
||||||
ret.Add(p);
|
ret.Add(p);
|
||||||
|
|
||||||
parent = p.IsGenericEnumerable() ? Expression.Parameter(p.GenericEnumerableType()) : p.Expression;
|
if (p.IsGenericEnumerable())
|
||||||
|
{
|
||||||
|
param = Expression.Parameter(p.GenericEnumerableType());
|
||||||
|
parent = param;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parent = p.PartExpression;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LambdaExpression GetLambdaExpression()
|
||||||
|
{
|
||||||
|
var lambda = Expression.Lambda(PartExpression, ParameterExpression);
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ParentGenericEnumerableType() => ParentExpression.Type.GenericTypeArguments.First();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,11 +296,11 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Expression ResolvePathForExpression(ParameterExpression param, string path)
|
public static Expression ResolvePathForExpression(ParameterExpression param, string path)
|
||||||
{
|
{
|
||||||
var parts = ExpressionPathPart.Break(param, path);
|
var parts = ExpressionPathPart.Split(param, path);
|
||||||
if (parts.Any(t => t.IsGenericEnumerable()))
|
if (parts.Any(t => t.IsGenericEnumerable()))
|
||||||
throw new Exception("this method does not support collection handling");
|
throw new Exception("this method does not support collection handling");
|
||||||
|
|
||||||
return parts.Last().Expression;
|
return parts.Last().PartExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConstantExpression GetConstantSameAsLeftOperator(Expression member, object value)
|
public static ConstantExpression GetConstantSameAsLeftOperator(Expression member, object value)
|
||||||
|
Loading…
Reference in New Issue
Block a user