query part breaker.
This commit is contained in:
parent
b80e9e433c
commit
dcd251f199
@ -1,4 +1,5 @@
|
|||||||
using PoweredSoft.DynamicLinq.Helpers;
|
using PoweredSoft.DynamicLinq.Dal.Pocos;
|
||||||
|
using PoweredSoft.DynamicLinq.Helpers;
|
||||||
using PoweredSoft.DynamicLinq.Test;
|
using PoweredSoft.DynamicLinq.Test;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -16,16 +17,15 @@ 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 path = "Posts.Comments.Id";
|
||||||
var expr = ResolveSelectExpression(param, path, SelectCollectionHandling.Flatten);
|
|
||||||
var expr2 = ResolveSelectExpression(param, path, SelectCollectionHandling.Flatten, true);
|
var parts = ExpressionPathPart.Break(param, "Posts.Comments.Id");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Expression ResolveSelectExpression(ParameterExpression param, string path, SelectCollectionHandling selectCollectionHandling = SelectCollectionHandling.LeaveAsIs, bool nullChecking = false)
|
|
||||||
{
|
|
||||||
var notCheckNullExpression = QueryablePathHelpers.NavigatePath(param, path,
|
/*
|
||||||
(before, member, isFirst, isLast) => member,
|
* (parent, innerExpression, innerExpressionLambda) =>
|
||||||
(before, member, isFirst, isLast) => member,
|
|
||||||
(parent, innerExpression, innerExpressionLambda) =>
|
|
||||||
{
|
{
|
||||||
var listGenericArgumentType = parent.Type.GetGenericArguments().First();
|
var listGenericArgumentType = parent.Type.GetGenericArguments().First();
|
||||||
Expression ret = null;
|
Expression ret = null;
|
||||||
@ -36,15 +36,6 @@ namespace PoweredSoft.DynamicLinq.ConsoleApp
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
);
|
*/
|
||||||
|
|
||||||
if (!nullChecking)
|
|
||||||
return notCheckNullExpression;
|
|
||||||
|
|
||||||
var type = notCheckNullExpression.Type;
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
PoweredSoft.DynamicLinq/ExpressionPathPart.cs
Normal file
36
PoweredSoft.DynamicLinq/ExpressionPathPart.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
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 Expression Expression { get; set; }
|
||||||
|
public bool IsNullable() => TypeHelpers.IsNullable(Expression.Type);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
var ret = new List<ExpressionPathPart>();
|
||||||
|
|
||||||
|
var parts = path.Split('.').ToList();
|
||||||
|
Expression parent = param;
|
||||||
|
parts.ForEach(part =>
|
||||||
|
{
|
||||||
|
var p = new ExpressionPathPart();
|
||||||
|
p.Expression = Expression.PropertyOrField(parent, part);
|
||||||
|
p.ParentExpression = parent;
|
||||||
|
ret.Add(p);
|
||||||
|
|
||||||
|
parent = p.IsGenericEnumerable() ? Expression.Parameter(p.GenericEnumerableType()) : p.Expression;
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -296,13 +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)
|
||||||
{
|
{
|
||||||
Expression ret = param;
|
var parts = ExpressionPathPart.Break(param, path);
|
||||||
var parts = path.Split('.').ToList();
|
if (parts.Any(t => t.IsGenericEnumerable()))
|
||||||
parts.ForEach(part =>
|
throw new Exception("this method does not support collection handling");
|
||||||
{
|
|
||||||
ret = Expression.PropertyOrField(ret, part);
|
return parts.Last().Expression;
|
||||||
});
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConstantExpression GetConstantSameAsLeftOperator(Expression member, object value)
|
public static ConstantExpression GetConstantSameAsLeftOperator(Expression member, object value)
|
||||||
|
@ -1,53 +1,12 @@
|
|||||||
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;
|
||||||
|
|
||||||
namespace PoweredSoft.DynamicLinq.Helpers
|
namespace PoweredSoft.DynamicLinq.Helpers
|
||||||
{
|
{
|
||||||
|
|
||||||
public static class QueryablePathHelpers
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,15 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
internal static Lazy<AssemblyBuilder> DynamicAssembly = new Lazy<AssemblyBuilder>(() => AssemblyBuilder.DefineDynamicAssembly(DynamicAssemblyName.Value, AssemblyBuilderAccess.Run));
|
internal static Lazy<AssemblyBuilder> DynamicAssembly = new Lazy<AssemblyBuilder>(() => AssemblyBuilder.DefineDynamicAssembly(DynamicAssemblyName.Value, AssemblyBuilderAccess.Run));
|
||||||
internal static Lazy<ModuleBuilder> DynamicModule = new Lazy<ModuleBuilder>(() => DynamicAssembly.Value.DefineDynamicModule("PoweredSoft.DynamicLinq.DynamicTypes"));*/
|
internal static Lazy<ModuleBuilder> DynamicModule = new Lazy<ModuleBuilder>(() => DynamicAssembly.Value.DefineDynamicModule("PoweredSoft.DynamicLinq.DynamicTypes"));*/
|
||||||
|
|
||||||
|
public static bool IsNullable(Type type)
|
||||||
|
{
|
||||||
|
if (!type.IsValueType)
|
||||||
|
return true; // ref-type
|
||||||
|
|
||||||
|
return Nullable.GetUnderlyingType(type) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static object ConvertFrom(Type type, object source)
|
public static object ConvertFrom(Type type, object source)
|
||||||
{
|
{
|
||||||
object ret = null;
|
object ret = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user