Exemple #1
0
        private TableQuery <T> AddOrderBy <U>(Expression <Func <T, U> > orderExpr, bool asc)
        {
            if (orderExpr.NodeType != ExpressionType.Lambda)
            {
                throw new NotSupportedException("Must be a predicate");
            }

            var lambda = (LambdaExpression)orderExpr;
            var mem    = lambda.Body as MemberExpression;

            if (mem == null || (mem.Expression.NodeType != ExpressionType.Parameter))
            {
                throw new NotSupportedException("Order By does not support: " + orderExpr);
            }

            TableQuery <T> q = Clone();

            if (q._orderBys == null)
            {
                q._orderBys = new List <Ordering>();
            }
            q._orderBys.Add(new Ordering
            {
                ColumnName = OrmHelper.GetColumnName(mem.Member),
                Ascending  = asc
            });
            return(q);
        }
Exemple #2
0
        private TableQuery <T> AddWith(params Expression <Func <T, object> >[] expressions)
        {
            TableQuery <T> q = Clone();

            if (q._withColumns == null)
            {
                q._withColumns = new List <WithColumn>();
            }
            foreach (var expression in expressions)
            {
                var member = GetMember(expression);
                q._withColumns.Add(new WithColumn {
                    ColumnName = OrmHelper.GetColumnName(member), Member = member
                });
            }
            return(q);
        }
Exemple #3
0
            internal Column(PropertyInfo prop)
            {
                _prop = prop;
                this._dataConverter = null;

                Name = OrmHelper.GetColumnName(prop);
                // If this type is Nullable<T> then Nullable.GetUnderlyingType returns the T,
                // otherwise it returns null, so get the the actual type instead
                ColumnType                  = OrmHelper.GetColumnType(prop);
                Collation                   = OrmHelper.GetCollation(prop);
                PrimaryKey                  = OrmHelper.GetPrimaryKey(prop);
                IsNullable                  = this.PrimaryKey == null && OrmHelper.GetIsColumnNullable(prop);
                IsAutoIncrement             = OrmHelper.GetIsAutoIncrement(prop);
                Unique                      = OrmHelper.GetUnique(prop);
                MaxStringLength             = OrmHelper.GetMaxStringLength(prop);
                Checks                      = OrmHelper.GetChecks(prop);
                DefaultValue                = OrmHelper.GetDefaultValue(prop);
                this.DataConverterAttribute = OrmHelper.GetDataConverter(prop);
            }
Exemple #4
0
        private CompileResult CompileExpr(Expression expr, List <object> queryArgs)
        {
            if (expr == null)
            {
                throw new NotSupportedException("Expression is NULL");
            }

            if (expr is BinaryExpression)
            {
                var bin = (BinaryExpression)expr;

                CompileResult leftr  = CompileExpr(bin.Left, queryArgs);
                CompileResult rightr = CompileExpr(bin.Right, queryArgs);

                //If either side is a parameter and is null, then handle the other side specially (for "is null"/"is not null")
                string text;
                if (leftr.CommandText == "?" && leftr.Value == null)
                {
                    text = CompileNullBinaryExpression(bin, rightr);
                }
                else if (rightr.CommandText == "?" && rightr.Value == null)
                {
                    text = CompileNullBinaryExpression(bin, leftr);
                }
                else
                {
                    text = "(" + leftr.CommandText + " " + GetSqlName(bin) + " " + rightr.CommandText + ")";
                }
                return(new CompileResult {
                    CommandText = text
                });
            }
            else if (expr.NodeType == ExpressionType.Call)
            {
                var call = (MethodCallExpression)expr;
                var args = new CompileResult[call.Arguments.Count];
                var obj  = call.Object != null?CompileExpr(call.Object, queryArgs) : null;

                string methodName = call.Method.Name;
                string sqlCall    = string.Empty;

                for (int i = 0; i < args.Length; i++)
                {
                    args[i] = CompileExpr(call.Arguments[i], queryArgs);
                }

                if (methodName == "Contains")
                {
                    if (args.Length == 1)
                    {
                        // string.Contains("xxx") or list.Contains(x)
                        if (call.Object != null && call.Object.Type == typeof(string))
                        {
                            sqlCall = "({0} like ('%' || {1} || '%'))";
                        }
                        else
                        {
                            sqlCall = "({1} in {0})";
                        }

                        sqlCall = string.Format(sqlCall, obj.CommandText, args[0].CommandText);
                    }
                    else if (args.Length == 2)
                    {
                        sqlCall = string.Format("({0} in {1})", args[1].CommandText, args[0].CommandText);
                    }
                }
                else if (methodName == "StartsWith" || methodName == "EndsWith")
                {
                    if (args.Length == 1)
                    {
                        if (methodName == "StartsWith")
                        {
                            sqlCall = "({0} like ({1} || '%'))";
                        }
                        else if (methodName == "EndsWith")
                        {
                            sqlCall = "({0} like ('%' || {1}))";
                        }

                        sqlCall = string.Format(sqlCall, obj.CommandText, args[0].CommandText);
                    }
                }
                else if (methodName == "Matches" && args.Length == 2)
                {
                    sqlCall = "({0} match {1})";
                    sqlCall = string.Format(sqlCall, args[0].CommandText, args[1].CommandText);
                }
                else
                {
                    var arguments = string.Join(",", args.Select(a => a.CommandText).ToArray());
                    sqlCall = string.Format("{0}({1})", methodName.ToLower(), arguments);
                }

                return(new CompileResult {
                    CommandText = sqlCall
                });
            }
            else if (expr.NodeType == ExpressionType.Constant)
            {
                var c = (ConstantExpression)expr;
                queryArgs.Add(c.Value);
                return(new CompileResult
                {
                    CommandText = "?",
                    Value = c.Value
                });
            }
            else if (expr.NodeType == ExpressionType.Convert)
            {
                var           u    = (UnaryExpression)expr;
                Type          ty   = u.Type;
                CompileResult valr = CompileExpr(u.Operand, queryArgs);

                var underlyingType = Nullable.GetUnderlyingType(ty);
                if (underlyingType != null)
                {
                    ty = underlyingType;
                }

                return(new CompileResult
                {
                    CommandText = valr.CommandText,
                    Value = valr.Value != null?Convert.ChangeType(valr.Value, ty, null) : null
                });
            }
            else if (expr.NodeType == ExpressionType.MemberAccess)
            {
                var mem = (MemberExpression)expr;

                if (mem.Expression.NodeType == ExpressionType.Parameter)
                {
                    //
                    // This is a column of our table, output just the column name
                    //
                    return(new CompileResult {
                        CommandText = "\"" + OrmHelper.GetColumnName(mem.Member) + "\""
                    });
                }
                else
                {
                    object obj = null;
                    if (mem.Expression != null)
                    {
                        CompileResult r = CompileExpr(mem.Expression, queryArgs);
                        if (r.Value == null)
                        {
                            throw new NotSupportedException("Member access failed to compile expression");
                        }
                        if (r.CommandText == "?")
                        {
                            queryArgs.RemoveAt(queryArgs.Count - 1);
                        }
                        obj = r.Value;
                    }

                    //
                    // Get the member value
                    //
                    object val = null;

                    if (mem.Member is PropertyInfo)
                    {
                        var m = (PropertyInfo)mem.Member;
                        val = m.GetValue(obj, null);
                    }
                    else if (mem.Member is FieldInfo)
                    {
#if SILVERLIGHT
                        val = Expression.Lambda(expr).Compile().DynamicInvoke();
#else
                        var m = (FieldInfo)mem.Member;
                        val = m.GetValue(obj);
#endif
                    }
                    else
                    {
                        throw new NotSupportedException("MemberExpr: " + mem.Member.GetType().Name);
                    }

                    //
                    // Work special magic for enumerables
                    //
                    if (val != null && val is IEnumerable && !(val is string))
                    {
                        var sb = new StringBuilder();
                        sb.Append("(");
                        string head = "";
                        foreach (object a in (IEnumerable)val)
                        {
                            queryArgs.Add(a);
                            sb.Append(head);
                            sb.Append("?");
                            head = ",";
                        }
                        sb.Append(")");
                        return(new CompileResult
                        {
                            CommandText = sb.ToString(),
                            Value = val
                        });
                    }
                    else
                    {
                        queryArgs.Add(val);
                        return(new CompileResult
                        {
                            CommandText = "?",
                            Value = val
                        });
                    }
                }
            }
            throw new NotSupportedException("Cannot compile: " + expr.NodeType.ToString());
        }