Exemplo n.º 1
0
        public SqlScriptBuilder <T> Where(Expression <Func <T, bool> > predict)
        {
            WherePart wherePart = _whereBuilder.ToSql(predict);

            _whereParts.Add(wherePart);
            return(this);
        }
Exemplo n.º 2
0
 public static WherePart Concat(string @operator, WherePart operand)
 {
     return(new WherePart()
     {
         Parameters = operand.Parameters,
         Sql = $"({@operator} {operand.Sql})"
     });
 }
Exemplo n.º 3
0
 public static WherePart Concat(WherePart left, string @operator, WherePart right)
 {
     return(new WherePart()
     {
         Parameters = left.Parameters.Union(right.Parameters).ToDictionary(kvp => kvp.Key, kvp => kvp.Value),
         Sql = $"({left.Sql} {@operator} {right.Sql})"
     });
 }
Exemplo n.º 4
0
        private WherePart Recurse(ref int i, Expression expression, bool isUnary = false, string prefix = null, string postfix = null)
        {
            if (expression is UnaryExpression)
            {
                var unary = (UnaryExpression)expression;
                return(WherePart.Concat(NodeTypeToString(unary.NodeType), Recurse(ref i, unary.Operand, true)));
            }
            if (expression is BinaryExpression)
            {
                var body = (BinaryExpression)expression;
                return(WherePart.Concat(Recurse(ref i, body.Left), NodeTypeToString(body.NodeType), Recurse(ref i, body.Right)));
            }
            if (expression is ConstantExpression)
            {
                var constant = (ConstantExpression)expression;
                var value    = constant.Value;
                if (value is int)
                {
                    return(WherePart.IsSql(value.ToString()));
                }
                if (value is string)
                {
                    value = prefix + (string)value + postfix;
                }
                if (value is bool && isUnary)
                {
                    return(WherePart.Concat(WherePart.IsParameter(i++, value), "=", WherePart.IsSql("1")));
                }
                return(WherePart.IsParameter(i++, value));
            }
            if (expression is MemberExpression)
            {
                var member = (MemberExpression)expression;

                if (member.Member is PropertyInfo)
                {
                    var property = (PropertyInfo)member.Member;
                    var colName  = property.Name;
                    if (isUnary && member.Type == typeof(bool))
                    {
                        return(WherePart.Concat(Recurse(ref i, expression), "=", WherePart.IsParameter(i++, true)));
                    }

                    if (property.PropertyType == typeof(DateTime) && property.ReflectedType == typeof(DateTime))
                    {
                        DateTime datetime         = (DateTime)property.GetValue(property, null);
                        string   sqlFormattedDate = datetime.Date.ToString("yyyy-MM-dd");
                        sqlFormattedDate = $"'{sqlFormattedDate}'";
                        return(WherePart.IsSql(sqlFormattedDate));
                    }
                    return(WherePart.IsSql(colName));
                }
                if (member.Member is FieldInfo)
                {
                    var value = GetValue(member);
                    if (value is string)
                    {
                        value = prefix + (string)value + postfix;
                    }
                    return(WherePart.IsParameter(i++, value));
                }
                throw new Exception($"Expression does not refer to a property or field: {expression}");
            }
            if (expression is MethodCallExpression)
            {
                var methodCall = (MethodCallExpression)expression;
                // LIKE queries:
                if (methodCall.Method == typeof(string).GetMethod("Contains", new[] { typeof(string) }))
                {
                    return(WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], prefix: "%", postfix: "%")));
                }
                if (methodCall.Method == typeof(string).GetMethod("StartsWith", new[] { typeof(string) }))
                {
                    return(WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], postfix: "%")));
                }
                if (methodCall.Method == typeof(string).GetMethod("EndsWith", new[] { typeof(string) }))
                {
                    return(WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], prefix: "%")));
                }
                // IN queries:
                if (methodCall.Method.Name == "Contains")
                {
                    Expression collection;
                    Expression property;
                    if (methodCall.Method.IsDefined(typeof(ExtensionAttribute)) && methodCall.Arguments.Count == 2)
                    {
                        collection = methodCall.Arguments[0];
                        property   = methodCall.Arguments[1];
                    }
                    else if (!methodCall.Method.IsDefined(typeof(ExtensionAttribute)) && methodCall.Arguments.Count == 1)
                    {
                        collection = methodCall.Object;
                        property   = methodCall.Arguments[0];
                    }
                    else
                    {
                        throw new Exception("Unsupported method call: " + methodCall.Method.Name);
                    }
                    var values = (IEnumerable)GetValue(collection);
                    return(WherePart.Concat(Recurse(ref i, property), "IN", WherePart.IsCollection(ref i, values)));
                }
                if (methodCall.Type == typeof(DateTime))
                {
                    //DateTime datetime = (DateTime)property.GetValue(property, null);
                    //string sqlFormattedDate = datetime.Date.ToString("yyyy-MM-dd");
                    //sqlFormattedDate = $"'{sqlFormattedDate}'";
                    //return WherePart.IsSql(sqlFormattedDate);
                    MethodInfo methodInfo = methodCall.Method;

                    if (methodInfo != null)
                    {
                        object          result        = null;
                        ParameterInfo[] parameters    = methodInfo.GetParameters();
                        object          classInstance = Activator.CreateInstance(typeof(DateTime), null);

                        if (parameters.Length == 0)
                        {
                            // This works fine
                            result = methodInfo.Invoke(classInstance, null);
                        }
                        else
                        {
                            object[] parametersArray = new object[] { 10 };

                            // The invoke does NOT work;
                            // it throws "Object does not match target type"
                            result = methodInfo.Invoke(classInstance, parametersArray);
                        }
                    }

                    string vl = "";
                }
                throw new Exception("Unsupported method call: " + methodCall.Method.Name);
            }
            throw new Exception("Unsupported expression: " + expression.GetType().Name);
        }