better expression logic should be easier to implement null checks now ;)
This commit is contained in:
parent
327d141c8e
commit
5568d15075
@ -64,7 +64,7 @@ namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|||||||
|
|
||||||
// the builder.
|
// the builder.
|
||||||
var per = new PathExpressionResolver(ep);
|
var per = new PathExpressionResolver(ep);
|
||||||
per.NullChecking = SelectNullHandling.Handle;
|
per.NullHandling = SelectNullHandling.Handle;
|
||||||
per.Resolve();
|
per.Resolve();
|
||||||
|
|
||||||
// the result expression.
|
// the result expression.
|
||||||
@ -76,7 +76,7 @@ namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|||||||
|
|
||||||
public class PathExpressionResolver
|
public class PathExpressionResolver
|
||||||
{
|
{
|
||||||
public SelectNullHandling NullChecking { get; set; } = SelectNullHandling.LeaveAsIs;
|
public SelectNullHandling NullHandling { get; set; } = SelectNullHandling.LeaveAsIs;
|
||||||
public SelectCollectionHandling CollectionHandling { get; set; } = SelectCollectionHandling.LeaveAsIs;
|
public SelectCollectionHandling CollectionHandling { get; set; } = SelectCollectionHandling.LeaveAsIs;
|
||||||
public ExpressionParser Parser { get; protected set; }
|
public ExpressionParser Parser { get; protected set; }
|
||||||
|
|
||||||
@ -97,8 +97,64 @@ namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|||||||
// group the piece by common parameters
|
// group the piece by common parameters
|
||||||
var groups = Parser.GroupBySharedParameters();
|
var groups = Parser.GroupBySharedParameters();
|
||||||
|
|
||||||
// compiled lambdas.
|
Expression ce = null;
|
||||||
var groupLambdas = groups.Select(group => group.CompileGroup(NullChecking)).ToList();
|
groups.ReversedForEach(group =>
|
||||||
|
{
|
||||||
|
if (ce == null)
|
||||||
|
{
|
||||||
|
var ge = group.CompileGroup(NullHandling);
|
||||||
|
var gl = Expression.Lambda(ge, group.Parameter);
|
||||||
|
|
||||||
|
if (group.Parent == null)
|
||||||
|
{
|
||||||
|
ce = gl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = group.Parent;
|
||||||
|
var parentExpression = parent.CompileGroup(NullHandling);
|
||||||
|
var selectType = parent.GroupEnumerableType();
|
||||||
|
var select = Expression.Call(typeof(Enumerable), "Select",
|
||||||
|
new Type[] { selectType, ge.Type },
|
||||||
|
parentExpression, gl);
|
||||||
|
ce = select;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (group.Parent == null)
|
||||||
|
{
|
||||||
|
ce = Expression.Lambda(ce, group.Parameter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = group.Parent;
|
||||||
|
var parentExpression = parent.CompileGroup(NullHandling);
|
||||||
|
var selectType = parent.GroupEnumerableType();
|
||||||
|
var currentExpressionLambda = Expression.Lambda(ce, group.Parameter);
|
||||||
|
ce = Expression.Call(typeof(Enumerable), "Select",
|
||||||
|
new Type[] { selectType, ce.Type },
|
||||||
|
parentExpression, currentExpressionLambda);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Expression JoinGroups(IEnumerable<ExpressionParserPieceGroup> groups, Expression result = null)
|
||||||
|
{
|
||||||
|
var lastGroup = groups.Last();
|
||||||
|
var lastGroupExpression = lastGroup.CompileGroup(NullHandling);
|
||||||
|
var lastGroupExpressionLambda = Expression.Lambda(lastGroupExpression, lastGroup.Parameter);
|
||||||
|
|
||||||
|
if (lastGroup.Parent == null)
|
||||||
|
return lastGroupExpressionLambda;
|
||||||
|
|
||||||
|
var parent = lastGroup.Parent;
|
||||||
|
var parentExpression = parent.CompileGroup(NullHandling);
|
||||||
|
var selectType = parent.GroupEnumerableType();
|
||||||
|
|
||||||
|
var select = Expression.Call(typeof(Enumerable), "Select",
|
||||||
|
new Type[] { selectType, lastGroupExpression.Type },
|
||||||
|
parentExpression, lastGroupExpressionLambda);
|
||||||
|
return select;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Expression RecursiveSelect(List<ExpressionParserPiece> pieces)
|
protected Expression RecursiveSelect(List<ExpressionParserPiece> pieces)
|
||||||
|
@ -62,10 +62,11 @@ namespace PoweredSoft.DynamicLinq.Parser
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExpressionParserPieceGroup CreateAndAddGroup(List<ExpressionParserPieceGroup> groups, ParameterExpression parameter)
|
private ExpressionParserPieceGroup CreateAndAddGroup(List<ExpressionParserPieceGroup> groups, ParameterExpression parameter, ExpressionParserPieceGroup parent)
|
||||||
{
|
{
|
||||||
var group = new ExpressionParserPieceGroup();
|
var group = new ExpressionParserPieceGroup();
|
||||||
group.ParameterExpression = parameter;
|
group.Parameter = parameter;
|
||||||
|
group.Parent = parent;
|
||||||
groups.Add(group);
|
groups.Add(group);
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
@ -74,12 +75,12 @@ namespace PoweredSoft.DynamicLinq.Parser
|
|||||||
{
|
{
|
||||||
var groups = new List<ExpressionParserPieceGroup>();
|
var groups = new List<ExpressionParserPieceGroup>();
|
||||||
|
|
||||||
var group = CreateAndAddGroup(groups, Parameter);
|
var group = CreateAndAddGroup(groups, Parameter, null);
|
||||||
Pieces.ForEach(piece =>
|
Pieces.ForEach(piece =>
|
||||||
{
|
{
|
||||||
group.Pieces.Add(piece);
|
group.Pieces.Add(piece);
|
||||||
if (piece.IsGenericEnumerable)
|
if (piece.IsGenericEnumerable)
|
||||||
group = CreateAndAddGroup(groups, Expression.Parameter(piece.EnumerableType));
|
group = CreateAndAddGroup(groups, Expression.Parameter(piece.EnumerableType), group);
|
||||||
});
|
});
|
||||||
|
|
||||||
return groups;
|
return groups;
|
||||||
|
@ -9,10 +9,11 @@ namespace PoweredSoft.DynamicLinq.Parser
|
|||||||
public class ExpressionParserPieceGroup
|
public class ExpressionParserPieceGroup
|
||||||
{
|
{
|
||||||
public List<ExpressionParserPiece> Pieces { get; set; } = new List<ExpressionParserPiece>();
|
public List<ExpressionParserPiece> Pieces { get; set; } = new List<ExpressionParserPiece>();
|
||||||
public ParameterExpression ParameterExpression { get; set; }
|
public ParameterExpression Parameter { get; set; }
|
||||||
|
public ExpressionParserPieceGroup Parent { get; set; }
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public override string ToString() => $"{ParameterExpression?.ToString()} is {ParameterExpression?.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)
|
public object CompileSimpleExpress(SelectNullHandling nullHandling)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -13,16 +14,19 @@ namespace PoweredSoft.DynamicLinq.Parser
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LambdaExpression CompileGroup(this ExpressionParserPieceGroup group, SelectNullHandling NullHandling)
|
public static Expression CompileGroup(this ExpressionParserPieceGroup group, SelectNullHandling NullHandling)
|
||||||
{
|
{
|
||||||
var expr = group.ParameterExpression as Expression;
|
var expr = group.Parameter as Expression;
|
||||||
group.Pieces.ForEach(piece =>
|
group.Pieces.ForEach(piece =>
|
||||||
{
|
{
|
||||||
expr = Expression.PropertyOrField(expr, piece.Name);
|
expr = Expression.PropertyOrField(expr, piece.Name);
|
||||||
});
|
});
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
var ret = Expression.Lambda(expr, group.ParameterExpression);
|
public static Type GroupEnumerableType(this ExpressionParserPieceGroup group)
|
||||||
return ret;
|
{
|
||||||
|
return group.Pieces.Last().EnumerableType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user