/// <summary> /// Recursively translates an Expression to an LDAP filter (RFC 1960). /// See formal definition of RFC 1960 at the bottom of this Microsoft doc page. /// https://docs.microsoft.com/en-us/windows/desktop/adsi/search-filter-syntax /// </summary> /// <param name="expr">The Expression body to convert.</param> /// <param name="p">The ParameterExpression associated with the body.</param> /// <returns>A string containing an equivalent LDAP filter.</returns> public string ExpressionToString(Expression expr, IReadOnlyCollection <ParameterExpression> p) { switch (expr.NodeType) { case ExpressionType.MemberAccess: return(_MemberToString(expr as MemberExpression, p)); case ExpressionType.Constant: return(_ConstExprToString(expr, p)); case ExpressionType.AndAlso: return(BooleanAlgebra.AndOrExprToString(expr, p, "&")); case ExpressionType.OrElse: return(BooleanAlgebra.AndOrExprToString(expr, p, "|")); case ExpressionType.Not: return(BooleanAlgebra.NotExprToString(expr, p)); case ExpressionType.Equal: return(_MaybeStringCompareToExpr(expr, p, "=") ?? _ComparisonExprToString(expr, p, "=")); case ExpressionType.GreaterThanOrEqual: return(_MaybeStringCompareToExpr(expr, p, ">=") ?? _ComparisonExprToString(expr, p, ">=")); case ExpressionType.LessThanOrEqual: return(_MaybeStringCompareToExpr(expr, p, "<=") ?? _ComparisonExprToString(expr, p, "<=")); case ExpressionType.Call: return(_CallExprToString(expr, p)); // These are not implemented in RFC 1960, so translate via negation. case ExpressionType.GreaterThan: return(_Negate(_MaybeStringCompareToExpr(expr, p, "<=", ">") ?? _ComparisonExprToString(expr, p, /* not */ "<="))); case ExpressionType.LessThan: return(_Negate(_MaybeStringCompareToExpr(expr, p, ">=", "<") ?? _ComparisonExprToString(expr, p, /* not */ ">="))); case ExpressionType.NotEqual: return(_Negate(_MaybeStringCompareToExpr(expr, p, /* not */ "=") ?? _ComparisonExprToString(expr, p, /* not */ "="))); case ExpressionType.Conditional: /* ternary */ return(_TernaryToBooleanAlgebra(expr, p)); // Low-priority/do not implement: default: throw new NotImplementedException( $"Linq-to-LDAP not implemented for {expr.NodeType}. \n" + "Use local variables to remove algebraic expressions and method calls, \n" + "and reduce Linq expression complexity to boolean algebra and string ops.\n" + "Please see the Linq2Ldap project site."); } }
public CompilerCore( CompilerOptions options, Strings strings = null, BooleanAlgebra booleanAlgebra = null, ValueUtil valueUtil = null ) { Options = options; Strings = strings ?? new Strings(this); BooleanAlgebra = booleanAlgebra ?? new BooleanAlgebra(this); ValueUtil = valueUtil ?? new ValueUtil(Options); }