internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, Expression update, IBuildContext select, List <SqlQuery.SetExpression> items) { var ext = extract.Body; if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update)) { builder.AsParameters.Add(update); } while (ext.NodeType == ExpressionType.Convert || ext.NodeType == ExpressionType.ConvertChecked) { ext = ((UnaryExpression)ext).Operand; } if (ext.NodeType != ExpressionType.MemberAccess || ext.GetRootObject() != extract.Parameters[0]) { throw new LinqException("Member expression expected for the 'Set' statement."); } var body = (MemberExpression)ext; var member = body.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } var column = select.ConvertToSql( body, 1, ConvertFlags.Field); //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field); if (column.Length == 0) { throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name); } var expr = builder.ConvertToSql(select, update, false, false); if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(update.Type)) { var memberAccessor = TypeAccessor.GetAccessor(body.Member.DeclaringType)[body.Member.Name]; ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); } items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); }
static void BuildJoin( ExpressionBuilder builder, SqlQuery.FromClause.Join join, IBuildContext outerKeyContext, Expression outerKeySelector, IBuildContext innerKeyContext, Expression innerKeySelector, IBuildContext countKeyContext, SqlQuery countSql) { var predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, innerKeyContext, innerKeySelector); if (predicate != null) { join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate)); } else { join .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector)).Equal .Expr(builder.ConvertToSql(innerKeyContext, innerKeySelector)); } predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, countKeyContext, innerKeySelector); if (predicate != null) { countSql.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); } else { countSql.Where .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector)).Equal .Expr(builder.ConvertToSql(countKeyContext, innerKeySelector)); } }
internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, Expression update, IBuildContext select) { var pi = extract.Body; if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update)) { builder.AsParameters.Add(update); } while (pi.NodeType == ExpressionType.Convert || pi.NodeType == ExpressionType.ConvertChecked) { pi = ((UnaryExpression)pi).Operand; } if (pi.NodeType != ExpressionType.MemberAccess) { throw new LinqException("Member expression expected for the 'Set' statement."); } var body = (MemberExpression)pi; var member = body.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } var column = select.ConvertToSql( Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field); if (column.Length == 0) { throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name); } var expr = builder.ConvertToSql(select, update); if (expr is SqlParameter && update.Type.IsEnum) { ((SqlParameter)expr).SetEnumConverter(update.Type, builder.MappingSchema); } select.SqlQuery.Set.Items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); }
internal static void BuildSetter( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression setter, IBuildContext into, IBuildContext sequence) { if (setter.Body.NodeType != ExpressionType.MemberInit) { throw new LinqException("Object initializer expected for insert statement."); } var body = (MemberInitExpression)setter.Body; var ex = body; var ctx = new ExpressionContext(buildInfo.Parent, sequence, setter); for (var i = 0; i < ex.Bindings.Count; i++) { var binding = ex.Bindings[i]; var member = binding.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } if (binding is MemberAssignment) { var ma = binding as MemberAssignment; var column = into.ConvertToSql( Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field); var expr = builder.ConvertToSql(ctx, ma.Expression); if (expr is SqlParameter && ma.Expression.Type.IsEnum) { ((SqlParameter)expr).SetEnumConverter(ma.Expression.Type, builder.MappingSchema); } sequence.SqlQuery.Set.Items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); } else { throw new InvalidOperationException(); } } }
internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, LambdaExpression update, IBuildContext select) { var pi = extract.Body; while (pi.NodeType == ExpressionType.Convert || pi.NodeType == ExpressionType.ConvertChecked) { pi = ((UnaryExpression)pi).Operand; } if (pi.NodeType != ExpressionType.MemberAccess) { throw new LinqException("Member expression expected for the 'Set' statement."); } var body = (MemberExpression)pi; var member = body.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } var sql = select.SqlQuery; var column = sql.Set.Into != null ? sql.Set.Into.Fields[member.Name] : select.ConvertToSql( Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql; var ctx = new ExpressionContext(buildInfo.Parent, select, update); var expr = builder.ConvertToSql(ctx, update.Body); if (expr is SqlParameter && update.Body.Type.IsEnum) { ((SqlParameter)expr).SetEnumConverter(update.Body.Type, builder.MappingSchema); } sql.Set.Items.Add(new SqlQuery.SetExpression(column, expr)); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var arg = methodCall.Arguments[1].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) arg = ((LambdaExpression)arg).Body.Unwrap(); var expr = builder.ConvertToSql(sequence, arg, false); if (methodCall.Method.Name == "Take") { BuildTake(builder, sequence, expr); } else { BuildSkip(builder, sequence, sequence.SqlQuery.Select.SkipValue, expr); } return sequence; }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var arg = methodCall.Arguments[1].Unwrap(); if (arg.NodeType == ExpressionType.Lambda) { arg = ((LambdaExpression)arg).Body.Unwrap(); } var expr = builder.ConvertToSql(sequence, arg); if (methodCall.Method.Name == "Take") { BuildTake(builder, sequence, expr); } else { BuildSkip(builder, sequence, sequence.SqlQuery.Select.SkipValue, expr); } return(sequence); }
internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, Expression update, IBuildContext select, SqlTable table, List <SqlQuery.SetExpression> items) { var ext = extract.Body; if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update)) { builder.AsParameters.Add(update); } while (ext.NodeType == ExpressionType.Convert || ext.NodeType == ExpressionType.ConvertChecked) { ext = ((UnaryExpression)ext).Operand; } if (ext.NodeType != ExpressionType.MemberAccess || ext.GetRootObject() != extract.Parameters[0]) { throw new LinqException("Member expression expected for the 'Set' statement."); } var body = (MemberExpression)ext; var member = body.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } var members = body.GetMembers(); var name = members .Skip(1) .Select(ex => { var me = ex as MemberExpression; if (me == null) { return(null); } var m = me.Member; if (m is MethodInfo) { m = TypeHelper.GetPropertyByMethod((MethodInfo)m); } return(m); }) .Where(m => m != null && !TypeHelper.IsNullableValueMember(m)) .Select(m => m.Name) .Aggregate((s1, s2) => s1 + "." + s2); if (table != null && !table.Fields.ContainsKey(name)) { throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, name); } ISqlExpression column; if (table != null) { column = table.Fields[name]; } else { var sql = select.ConvertToSql( body, 1, ConvertFlags.Field); //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql; if (sql.Length == 0) { throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name); } column = sql[0].Sql; } var expr = builder.ConvertToSql(select, update, false, false); SetConverter(builder.MappingSchema, member, expr); items.Add(new SqlQuery.SetExpression(column, expr)); }
static void BuildJoin( ExpressionBuilder builder, SqlQuery.FromClause.Join join, ExpressionContext outerKeyContext, Expression outerKeySelector, ExpressionContext innerKeyContext, Expression innerKeySelector, ExpressionContext countKeyContext, SqlQuery countSql) { var predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, innerKeyContext, innerKeySelector); if (predicate != null) join.JoinedTable.Condition.Conditions.Add(new SqlQuery.Condition(false, predicate)); else join .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector)).Equal .Expr(builder.ConvertToSql(innerKeyContext, innerKeySelector)); predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, countKeyContext, innerKeySelector); if (predicate != null) countSql.Where.SearchCondition.Conditions.Add(new SqlQuery.Condition(false, predicate)); else countSql.Where .Expr(builder.ConvertToSql(outerKeyContext, outerKeySelector)).Equal .Expr(builder.ConvertToSql(countKeyContext, innerKeySelector)); }