well advanced to start new way of null checking.
This commit is contained in:
@@ -55,8 +55,8 @@ namespace PoweredSoft.DynamicLinq
|
||||
|
||||
public enum SelectCollectionHandling
|
||||
{
|
||||
Select,
|
||||
SelectMany
|
||||
LeaveAsIs,
|
||||
Flatten
|
||||
}
|
||||
|
||||
internal static class Constants
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace PoweredSoft.DynamicLinq.Fluent
|
||||
return this;
|
||||
}
|
||||
|
||||
public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.Select)
|
||||
public SelectBuilder PathToList(string path, string propertyName = null, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs)
|
||||
{
|
||||
if (propertyName == null)
|
||||
propertyName = path.Split('.').LastOrDefault();
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
||||
var innerExpression = InternalResolvePathExpression(step + 1, innerParam, parts.Skip(1).ToList(), selectCollectionHandling, nullChecking);
|
||||
var lambda = Expression.Lambda(innerExpression, innerParam);
|
||||
|
||||
if (selectCollectionHandling == SelectCollectionHandling.Select)
|
||||
if (selectCollectionHandling == SelectCollectionHandling.LeaveAsIs)
|
||||
ret = Expression.Call(typeof(Enumerable), "Select", new Type[] { listGenericArgumentType, innerExpression.Type }, memberExpression, lambda);
|
||||
else
|
||||
ret = Expression.Call(typeof(Enumerable), "SelectMany", new Type[] { listGenericArgumentType, innerExpression.Type.GenericTypeArguments.First() }, memberExpression, lambda);
|
||||
@@ -527,7 +527,7 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool IsGenericEnumerable(MemberExpression member) => IsGenericEnumerable(member.Type);
|
||||
public static bool IsGenericEnumerable(Expression member) => IsGenericEnumerable(member.Type);
|
||||
public static bool IsGenericEnumerable(Type type)
|
||||
{
|
||||
if (!type.IsGenericType)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace PoweredSoft.DynamicLinq.Helpers
|
||||
{
|
||||
public static class QueryablePathHelpers
|
||||
{
|
||||
public delegate Expression SimplePathNavigated(Expression before, MemberExpression member, bool isFirst, bool isLast);
|
||||
public delegate Expression CollectionPathNavigated(Expression before, MemberExpression member, bool isFirst, bool isLast);
|
||||
public delegate Expression CollectionHandling(Expression parent, Expression innerExpression, LambdaExpression innerExpressionLambda);
|
||||
|
||||
internal static Expression InternalNavigatePath(Expression before, List<string> parts, SimplePathNavigated simple, CollectionPathNavigated collection, CollectionHandling collectionHandling)
|
||||
{
|
||||
var isFirst = before is ParameterExpression;
|
||||
var isLast = parts.Count() == 1;
|
||||
var currentExpression = Expression.PropertyOrField(before, parts.First());
|
||||
var isEnumerable = QueryableHelpers.IsGenericEnumerable(currentExpression);
|
||||
|
||||
// allow interaction through callback.
|
||||
var alteredExpression = isEnumerable ? simple(before, currentExpression, isFirst, isLast) : collection(before, currentExpression, isFirst, isLast);
|
||||
|
||||
// if its last we are done :)
|
||||
if (isLast)
|
||||
return alteredExpression;
|
||||
|
||||
// not enumerable pretty simple.
|
||||
if (!isEnumerable)
|
||||
return InternalNavigatePath(alteredExpression, parts.Skip(1).ToList(), simple, collection, collectionHandling);
|
||||
|
||||
// enumerable.
|
||||
var listGenericArgumentType = alteredExpression.Type.GetGenericArguments().First();
|
||||
|
||||
// sub param.
|
||||
var innerParameter = Expression.Parameter(listGenericArgumentType);
|
||||
var innerExpr = InternalNavigatePath(innerParameter, parts.Skip(1).ToList(), simple, collection, collectionHandling);
|
||||
var lambda = Expression.Lambda(innerExpr, innerParameter);
|
||||
var collectionHandlingResult = collectionHandling(alteredExpression, innerExpr, lambda);
|
||||
return collectionHandlingResult;
|
||||
}
|
||||
|
||||
public static Expression NavigatePath(ParameterExpression param, string path,
|
||||
SimplePathNavigated simple,
|
||||
CollectionPathNavigated collection,
|
||||
CollectionHandling collectionHandling)
|
||||
{
|
||||
var parts = path.Split('.').ToList();
|
||||
return InternalNavigatePath(param, parts, simple, collection, collectionHandling);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user