public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags) { if (_innerContext != null) { return(_innerContext.ConvertToSql(expression, level, flags)); } return(base.ConvertToSql(expression, level, flags)); }
public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags) { if (expression != null) { switch (flags) { case ConvertFlags.Field: { var root = Builder.GetRootObject(expression); if (root.NodeType == ExpressionType.Parameter) { if (_sourceParameters.Contains(root)) { return(_source.ConvertToSql(expression, level, flags)); } return(_target !.ConvertToSql(expression, level, flags)); } if (root is ContextRefExpression contextRef) { return(contextRef.BuildContext.ConvertToSql(expression, level, flags)); } break; } } } throw new LinqException("'{0}' cannot be converted to SQL.", expression); }
internal static void BuildSetter( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression setter, IBuildContext into, List <SqlQuery.SetExpression> items, IBuildContext sequence) { var path = Expression.Parameter(setter.Body.Type, "p"); var ctx = new ExpressionContext(buildInfo.Parent, sequence, setter); if (setter.Body.NodeType == ExpressionType.MemberInit) { var ex = (MemberInitExpression)setter.Body; var p = sequence.Parent; BuildSetter(builder, into, items, ctx, ex, path); builder.ReplaceParent(ctx, p); } else { var sqlInfo = ctx.ConvertToSql(setter.Body, 0, ConvertFlags.All); foreach (var info in sqlInfo) { if (info.Members.Count == 0) { throw new LinqException("Object initializer expected for insert statement."); } if (info.Members.Count != 1) { throw new InvalidOperationException(); } var member = info.Members[0]; var pe = Expression.MakeMemberAccess(path, member); var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); var expr = info.Sql; if (expr is SqlParameter) { SetConverter(builder.MappingSchema, member, expr); //var type = member.MemberType == MemberTypes.Field ? // ((FieldInfo) member).FieldType : // ((PropertyInfo)member).PropertyType; //if (TypeHelper.IsEnumOrNullableEnum(type)) //{ // var memberAccessor = TypeAccessor.GetAccessor(member.DeclaringType)[member.Name]; // ((SqlParameter)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); //} } items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); } } }
static void BuildSetter( ExpressionBuilder builder, IBuildContext into, List <SelectQuery.SetExpression> items, IBuildContext ctx, MemberInitExpression expression, Expression path) { foreach (var binding in expression.Bindings) { var member = binding.Member; if (member is MethodInfo) { member = ((MethodInfo)member).GetPropertyInfo(); } if (binding is MemberAssignment) { var ma = binding as MemberAssignment; var pe = Expression.MakeMemberAccess(path, member); if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result) { BuildSetter( builder, into, items, ctx, (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member)); } else { var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); var expr = builder.ConvertToSqlExpression(ctx, ma.Expression); if (expr.ElementType == QueryElementType.SqlParameter) { var parm = (SqlParameter)expr; var field = column[0].Sql is SqlField ? (SqlField)column[0].Sql : (SqlField)((SelectQuery.Column)column[0].Sql).Expression; if (parm.DataType == DataType.Undefined) { parm.DataType = field.DataType; } } items.Add(new SelectQuery.SetExpression(column[0].Sql, expr)); } } else { throw new InvalidOperationException(); } } }
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 BuildSetter( ExpressionBuilder builder, IBuildContext into, List <SqlQuery.SetExpression> items, IBuildContext ctx, MemberInitExpression expression, Expression path) { foreach (var binding in expression.Bindings) { var member = binding.Member; if (member is MethodInfo) { member = TypeHelper.GetPropertyByMethod((MethodInfo)member); } if (binding is MemberAssignment) { var ma = binding as MemberAssignment; var pe = Expression.MakeMemberAccess(path, member); if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result) { BuildSetter( builder, into, items, ctx, (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member)); } else { var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); var expr = builder.ConvertToSqlExpression(ctx, ma.Expression, false); if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(ma.Expression.Type)) { var memberAccessor = TypeAccessor.GetAccessor(ma.Member.DeclaringType)[ma.Member.Name]; ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema); } items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); } } else { throw new InvalidOperationException(); } } }
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)); }
static ISqlPredicate MakeIsPredicate(ExpressionBuilder builder, IBuildContext context, Type fromType, Type toType) { var table = new SqlTable(builder.MappingSchema, fromType); var mapper = builder.MappingSchema.GetEntityDescriptor(fromType); var discriminators = mapper.InheritanceMapping; return(builder.MakeIsPredicate(context, discriminators, toType, name => { var field = table.Fields.Values.First(f => f.Name == name); var member = field.ColumnDescriptor.MemberInfo; var expr = Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member); var sql = context.ConvertToSql(expr, 1, ConvertFlags.Field)[0].Sql; return sql; })); }
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 BuildSetter( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression setter, IBuildContext into, List <SelectQuery.SetExpression> items, IBuildContext sequence) { var path = Expression.Parameter(setter.Body.Type, "p"); var ctx = new ExpressionContext(buildInfo.Parent, sequence, setter); if (setter.Body.NodeType == ExpressionType.MemberInit) { var ex = (MemberInitExpression)setter.Body; var p = sequence.Parent; BuildSetter(builder, into, items, ctx, ex, path); builder.ReplaceParent(ctx, p); } else { var sqlInfo = ctx.ConvertToSql(setter.Body, 0, ConvertFlags.All); foreach (var info in sqlInfo) { if (info.Members.Count == 0) { throw new LinqException("Object initializer expected for insert statement."); } if (info.Members.Count != 1) { throw new InvalidOperationException(); } var member = info.Members[0]; var pe = Expression.MakeMemberAccess(path, member); var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); var expr = info.Sql; items.Add(new SelectQuery.SetExpression(column[0].Sql, expr)); } } }
static void BuildSetter( ExpressionBuilder builder, IBuildContext into, List <SqlQuery.SetExpression> items, IBuildContext ctx, MemberInitExpression expression, Expression path) { foreach (var binding in expression.Bindings) { var member = binding.Member; if (member is MethodInfo) { member = ((MethodInfo)member).GetPropertyInfo(); } if (binding is MemberAssignment) { var ma = binding as MemberAssignment; var pe = Expression.MakeMemberAccess(path, member); if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result) { BuildSetter( builder, into, items, ctx, (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member)); } else { var column = into.ConvertToSql(pe, 1, ConvertFlags.Field); var expr = builder.ConvertToSqlExpression(ctx, ma.Expression); items.Add(new SqlQuery.SetExpression(column[0].Sql, expr)); } } else { throw new InvalidOperationException(); } } }
internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, Expression update, IBuildContext select, List <SelectQuery.SetExpression> items) { var ext = extract.Body; if (!update.Type.IsConstantable() && !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 = ((MethodInfo)member).GetPropertyInfo(); } var column = select.ConvertToSql(body, 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); items.Add(new SelectQuery.SetExpression(column[0].Sql, expr)); }
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)); }
public static List <Tuple <SqlInfo, SqlInfo> > MatchSequences(IBuildContext source, IBuildContext destination) { var sourceInfos = source.ConvertToSql(null, 0, ConvertFlags.All).ToList(); var destInfos = destination.ConvertToSql(null, 0, ConvertFlags.All).ToList(); var result = new List <Tuple <SqlInfo, SqlInfo> >(); foreach (var info in sourceInfos) { if (info.MemberChain.Length == 0) { continue; } var destInfo = destInfos.FirstOrDefault(di => info.CompareMembers(di)); if (destInfo != null) { result.Add(Tuple.Create(info, destInfo)); } } return(result); }
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)); }
internal static void ParseSet( ExpressionBuilder builder, BuildInfo buildInfo, LambdaExpression extract, LambdaExpression update, IBuildContext select, SqlTable table, List <SelectQuery.SetExpression> items) { var ext = extract.Body; 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 = ((MethodInfo)member).GetPropertyInfo(); } 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 = ((MethodInfo)m).GetPropertyInfo(); } return(m); }) .Where(m => m != null && !m.IsNullableValueMember()) .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); } var column = table != null ? table.Fields[name] : select.ConvertToSql( body, 1, ConvertFlags.Field)[0].Sql; //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql; var sp = select.Parent; var ctx = new ExpressionContext(buildInfo.Parent, select, update); var expr = builder.ConvertToSqlExpression(ctx, update.Body); builder.ReplaceParent(ctx, sp); items.Add(new SelectQuery.SetExpression(column, expr)); }