2018-03-26 21:42:49 -04:00
|
|
|
|
using PoweredSoft.DynamicLinq.Dal.Pocos;
|
|
|
|
|
using PoweredSoft.DynamicLinq.Helpers;
|
2018-03-26 17:14:01 -04:00
|
|
|
|
using PoweredSoft.DynamicLinq.Test;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|
|
|
|
{
|
2018-03-27 20:06:04 -04:00
|
|
|
|
public class SelectExpression
|
2018-03-26 17:14:01 -04:00
|
|
|
|
{
|
|
|
|
|
static void Main(string[] args)
|
|
|
|
|
{
|
2018-03-27 09:43:07 -04:00
|
|
|
|
var q = new List<Author>().AsQueryable();
|
|
|
|
|
q.Select(t => new
|
|
|
|
|
{
|
|
|
|
|
Ids = t.Posts.SelectMany(t2 => t2.Comments.Select(t3 => t3.CommentLikes))
|
|
|
|
|
});
|
|
|
|
|
|
2018-03-27 20:22:27 -04:00
|
|
|
|
var expressionParser = new ExpressionParser(typeof(Author), "Posts.Comments.CommentLikes");
|
2018-03-27 09:43:07 -04:00
|
|
|
|
expressionParser.Parse();
|
2018-03-27 20:06:04 -04:00
|
|
|
|
|
|
|
|
|
var finalExpression = CreateSelectExpressionFromParsed(expressionParser, SelectCollectionHandling.Flatten, SelectNullHandling.LeaveAsIs);
|
|
|
|
|
}
|
2018-03-27 09:43:07 -04:00
|
|
|
|
|
2018-03-27 20:06:04 -04:00
|
|
|
|
public static Expression CreateSelectExpressionFromParsed(ExpressionParser expressionParser,
|
2018-03-26 22:30:36 -04:00
|
|
|
|
SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs,
|
|
|
|
|
SelectNullHandling nullChecking = SelectNullHandling.LeaveAsIs)
|
|
|
|
|
{
|
|
|
|
|
Type nullHandlingRightType = null;
|
|
|
|
|
Expression nullHandlingNullValue = null;
|
|
|
|
|
|
2018-03-27 20:06:04 -04:00
|
|
|
|
/*
|
2018-03-26 22:30:36 -04:00
|
|
|
|
if (nullChecking != SelectNullHandling.LeaveAsIs)
|
|
|
|
|
{
|
|
|
|
|
nullHandlingRightType = parts.Last().PartExpression.Type;
|
|
|
|
|
nullHandlingNullValue = nullChecking == SelectNullHandling.Default
|
|
|
|
|
? Expression.Default(nullHandlingRightType) as Expression
|
|
|
|
|
: Expression.New(nullHandlingRightType) as Expression;
|
2018-03-27 20:06:04 -04:00
|
|
|
|
}*/
|
2018-03-26 22:30:36 -04:00
|
|
|
|
|
|
|
|
|
// reversed :)
|
2018-03-27 20:06:04 -04:00
|
|
|
|
var reversedCopy = expressionParser.Groups.Select(t => t).ToList();
|
2018-03-26 22:30:36 -04:00
|
|
|
|
reversedCopy.Reverse();
|
|
|
|
|
|
2018-03-27 20:06:04 -04:00
|
|
|
|
MethodCallExpression lastSelectExpression = null;
|
2018-03-26 22:30:36 -04:00
|
|
|
|
Expression ret = null;
|
2018-03-27 20:06:04 -04:00
|
|
|
|
|
|
|
|
|
foreach(var t in reversedCopy)
|
2018-03-26 22:30:36 -04:00
|
|
|
|
{
|
2018-03-27 20:06:04 -04:00
|
|
|
|
if (true == t.Parent?.LastPiece().IsGenericEnumerable())
|
2018-03-26 22:30:36 -04:00
|
|
|
|
{
|
2018-03-27 20:06:04 -04:00
|
|
|
|
if (lastSelectExpression == null)
|
2018-03-27 20:22:27 -04:00
|
|
|
|
lastSelectExpression = RegroupSelectExpressions(t, selectCollectionHandling);
|
2018-03-26 22:30:36 -04:00
|
|
|
|
else
|
2018-03-27 20:22:27 -04:00
|
|
|
|
lastSelectExpression = RegroupSelectExpressions(t, lastSelectExpression, selectCollectionHandling);
|
2018-03-26 22:30:36 -04:00
|
|
|
|
}
|
2018-03-27 20:06:04 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = lastSelectExpression;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-27 20:22:27 -04:00
|
|
|
|
public static MethodCallExpression RegroupSelectExpressions(ExpressionParameterGroup group, SelectCollectionHandling selectCollectionHandling)
|
2018-03-27 20:06:04 -04:00
|
|
|
|
{
|
|
|
|
|
MethodCallExpression ret = null;
|
|
|
|
|
var lambda = group.CreateLambda();
|
|
|
|
|
var parentExpression = group.Parent.LastExpression();
|
|
|
|
|
var isParentExpressionGenericEnumerable = QueryableHelpers.IsGenericEnumerable(parentExpression);
|
|
|
|
|
var parentExpressionGenericEnumerableType = isParentExpressionGenericEnumerable ? parentExpression.Type.GenericTypeArguments.First() : null;
|
|
|
|
|
var lastPiece = group.LastPiece();
|
|
|
|
|
|
|
|
|
|
if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs || !lastPiece.IsGenericEnumerable())
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { parentExpressionGenericEnumerableType, lastPiece.Expression.Type }, parentExpression, lambda);
|
|
|
|
|
else
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { parentExpressionGenericEnumerableType, lastPiece.GetGenericEnumerableType() }, parentExpression, lambda);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-27 20:22:27 -04:00
|
|
|
|
public static MethodCallExpression RegroupSelectExpressions(ExpressionParameterGroup group, MethodCallExpression innerSelect, SelectCollectionHandling selectCollectionHandling)
|
2018-03-27 20:06:04 -04:00
|
|
|
|
{
|
|
|
|
|
var parent = group.Parent;
|
|
|
|
|
var parentLastPiece = parent.LastPiece();
|
|
|
|
|
|
|
|
|
|
MethodCallExpression ret = null;
|
|
|
|
|
var lambda = Expression.Lambda(innerSelect, group.Parameter);
|
|
|
|
|
if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs)
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { parentLastPiece.GetGenericEnumerableType(), innerSelect.Type }, parentLastPiece.Expression, lambda);
|
|
|
|
|
else
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { parentLastPiece.GetGenericEnumerableType(), innerSelect.Type.GenericTypeArguments.First() }, parentLastPiece.Expression, lambda);
|
|
|
|
|
|
2018-03-26 22:30:36 -04:00
|
|
|
|
return ret;
|
2018-03-26 17:14:01 -04:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-26 21:42:49 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* (parent, innerExpression, innerExpressionLambda) =>
|
2018-03-26 17:14:01 -04:00
|
|
|
|
{
|
|
|
|
|
var listGenericArgumentType = parent.Type.GetGenericArguments().First();
|
|
|
|
|
Expression ret = null;
|
|
|
|
|
if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs || !QueryableHelpers.IsGenericEnumerable(innerExpression))
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { listGenericArgumentType, innerExpression.Type }, parent, innerExpressionLambda);
|
|
|
|
|
else
|
|
|
|
|
ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { listGenericArgumentType, innerExpression.Type.GenericTypeArguments.First() }, parent, innerExpressionLambda);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2018-03-26 21:42:49 -04:00
|
|
|
|
*/
|
2018-03-26 17:14:01 -04:00
|
|
|
|
}
|
|
|
|
|
}
|