private static void InitializeContext(WhereBuilderContext context) { Type eltType = context.ElementType; ModelInfo info = ModelInfo.GetModelInfo(context.Arguments.GetType()); foreach (var mp in info.Properties.Where(o => !o.IsDefined(typeof(NonCriteriaAttribute)))) { context.CriteriaProperties.Add(mp); } }
private static void Build(WhereBuilderContext context) { InitializeContext(context); foreach (var mp in context.CriteriaProperties) { object value = mp.GetValue(context.Arguments); if (!context.Arguments.ResolveProperty(value, mp, context) && value != null) { ResolvePropertyDefault(value, mp, context); } } }
public static IQueryable <T> Build <T>(IQueryable <T> query, QueryArgs args) { WhereBuilderContext context = new WhereBuilderContext(query, args); Build(context); query = (IQueryable <T>)context.CurrentQuery; var current = context.Expression; if (current != null) { return(query.Where(Expression.Lambda <Func <T, bool> >(current, context.Parameter))); } else { return(query); } }
private static IEnumerable <MemberExpression> MapProperty(ModelPropertyInfo argumentProperty, WhereBuilderContext context) { var info = context.ElementModel; List <string> names = new List <string>(5); List <ModelPropertyInfo> chain = new List <ModelPropertyInfo>(5); names.AddRange(argumentProperty.Maps.Where(o => o.SourceType == info.ModelType).Select(o => o.PropertyName)); if (names.Count == 0) { names.Add(argumentProperty.Name); } foreach (string name in names.Distinct()) { chain.Clear(); ModelConvert.FillPropertyChain(info, name, chain); Debug.Assert(chain.Count > 0); MemberExpression member = null; foreach (var mp in chain) { member = Expression.MakeMemberAccess((Expression)member ?? context.Parameter, mp.PropertyInfo); } yield return(member); } }
private static void ResolvePropertyDefault(object value, ModelPropertyInfo mp, WhereBuilderContext context) { Criteria criteria = value as Criteria; if (criteria == null) { criteria = Criteria.Create(value, mp); } var members = MapProperty(mp, context); if (members != null) { Expression expr = null; foreach (var mb in members) { var expr1 = criteria.CreateExpression(mb, context); if (expr1 != null) { if (expr == null) { expr = expr1; } else { expr = Expression.OrElse(expr, expr1); } } } if (expr != null) { context.Append(expr); } } }
internal static bool ResolvePropertyExpressionOrCriteria(object value, ModelPropertyInfo argumentProperty, WhereBuilderContext context) { var method = context.Arguments.GetType().GetMethod("Resolve" + argumentProperty.Name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { argumentProperty.Type }, null); if (method != null) { Type retType = typeof(Expression <>).MakeGenericType(typeof(Func <,>).MakeGenericType(context.ElementType, typeof(bool))); if (method.ReturnType == retType) { LambdaExpression lambda = (LambdaExpression)method.Invoke(context.Arguments, new object[] { value }); if (lambda != null) { //ExpressionReplacementUtil util = new ExpressionReplacementUtil(lambda.Parameters[0], context.Parameter); //context.Append(util.Visit(lambda.Body)); context.Append(ReplacementVisitor.Replace(lambda.Body, lambda.Parameters[0], context.Parameter)); } return(true); } else if ((typeof(Criteria)).IsAssignableFrom(method.ReturnType)) { Criteria criteria = (Criteria)method.Invoke(context.Arguments, new object[] { value }); if (criteria != null) { ResolvePropertyDefault(criteria, argumentProperty, context); } return(true); } } return(false); }
internal static bool ResolvePropertyQueryable(object value, ModelPropertyInfo argumentProperty, WhereBuilderContext context) { Type argType = context.Arguments.GetType(); Type[] parameterTypes = new Type[] { typeof(IQueryable <>).MakeGenericType(context.ElementType), argumentProperty.Type }; var method = argType.GetMethod("Resolve" + argumentProperty.Name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); if (method == null && value != null && Nullable.GetUnderlyingType(argumentProperty.Type) == value.GetType()) { parameterTypes[1] = value.GetType(); method = argType.GetMethod("Resolve" + argumentProperty.Name, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null); } if (method != null && method.ReturnType == parameterTypes[0]) { var query = method.Invoke(context.Arguments, new object[] { context.CurrentQuery, value }); if (query != null) { context.CurrentQuery = (IQueryable)query; } return(true); } else { return(false); } }
internal protected virtual bool ResolveProperty(object value, ModelPropertyInfo argumentProperty, WhereBuilderContext context) { return(WhereBuilder.ResolvePropertyQueryable(value, argumentProperty, context) || WhereBuilder.ResolvePropertyExpressionOrCriteria(value, argumentProperty, context)); }
protected internal override Expression CreateExpression(MemberExpression member, WhereBuilderContext context) { if (Value == null) { return(null); } var value = Expression.Constant(Value, member.Type); if (Operator != StringOperator.Equal) { return(Expression.Call(member, TypicalLinqMethods.GetMethod("String" + Operator), value)); } else { return(Expression.Equal(member, value, true, null)); } }
protected internal override Expression CreateExpression(MemberExpression member, WhereBuilderContext context) { if (Value == null) { return(null); } var value = Expression.Constant(Value, member.Type); switch (Operator) { case ComparisonOperator.Equal: return(Expression.Equal(member, value)); case ComparisonOperator.LessThan: return(Expression.LessThan(member, value)); case ComparisonOperator.GreaterThan: return(Expression.GreaterThan(member, value)); case ComparisonOperator.LessThanOrEqual: return(Expression.LessThanOrEqual(member, value)); case ComparisonOperator.GreaterThanOrEqual: return(Expression.GreaterThanOrEqual(member, value)); default: throw new NotSupportedException("Comparision operator " + Operator + " is invalid."); } }
internal protected abstract Expression CreateExpression(MemberExpression member, WhereBuilderContext context);