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); }
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); }
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); }
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()); }