static bool IsMultipleQuery(MethodCallExpression ce, MappingSchema mappingSchema) { //TODO: Multiply query check should be smarter, possibly not needed if we create fallback mechanism return(!ce.IsQueryable(FirstSingleBuilder.MethodNames) && typeof(IEnumerable).IsSameOrParentOf(ce.Type) && ce.Type != typeof(string) && !ce.Type.IsArray && !ce.IsAggregate(mappingSchema)); }
ISqlExpression ConvertEnumerable(MethodCallExpression call) { if (call.IsAggregate(Builder.MappingSchema)) { if (call.Arguments[0].NodeType == ExpressionType.Call) { var arg = (MethodCallExpression)call.Arguments[0]; if (arg.Method.Name == "Select") { var arg0 = arg.Arguments[0].SkipPathThrough(); if (arg0.NodeType != ExpressionType.Call) { var l = (LambdaExpression)arg.Arguments[1].Unwrap(); var largs = l.Type.GetGenericArgumentsEx(); if (largs.Length == 2) { var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); var sql = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); return(new SqlFunction(call.Type, call.Method.Name, sql)); } } } } } if (call.Arguments[0].NodeType == ExpressionType.Call) { var ctx = Builder.GetSubQuery(this, call); if (Builder.DataContext.SqlProviderFlags.IsSubQueryColumnSupported) { return(ctx.SelectQuery); } var join = ctx.SelectQuery.CrossApply(); SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable); return(ctx.SelectQuery.Select.Columns[0]); } var args = new ISqlExpression[call.Arguments.Count - 1]; if (CountBuilder.MethodNames.Contains(call.Method.Name)) { if (args.Length > 0) { throw new InvalidOperationException(); } return(SqlFunction.CreateCount(call.Type, SelectQuery)); } var attribute = Builder.MappingSchema.GetAttribute <Sql.ExpressionAttribute>(call.Method.DeclaringType, call.Method, c => c.Configuration); if (attribute != null) { var expr = attribute.GetExpression(Builder.DataContext, SelectQuery, call, e => { var ex = e.Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); var res = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); return(res); } else { return(Builder.ConvertToSql(_element, ex, true)); } }); if (expr != null) { return(expr); } } if (call.Arguments.Count > 1) { for (var i = 1; i < call.Arguments.Count; i++) { var ex = call.Arguments[i].Unwrap(); if (ex is LambdaExpression) { var l = (LambdaExpression)ex; var p = _element.Parent; var ctx = new ExpressionContext(Parent, _element, l); args[i - 1] = Builder.ConvertToSql(ctx, l.Body, true); Builder.ReplaceParent(ctx, p); } else { args[i - 1] = Builder.ConvertToSql(_element, ex, true); } } } else { args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray(); } if (attribute != null) { return(attribute.GetExpression(call.Method, args)); } return(new SqlFunction(call.Type, call.Method.Name, args)); }
protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.IsAggregate(builder.MappingSchema)); }