Exemple #1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var functions = Sql.ExtensionAttribute.GetExtensionAttributes(methodCall, builder.MappingSchema);

            var root = methodCall.SkipMethodChain(builder.MappingSchema);

            // evaluating IQueryableContainer
            while (root.NodeType == ExpressionType.Constant && typeof(Sql.IQueryableContainer).IsSameOrParentOf(root.Type))
            {
                root = ((Sql.IQueryableContainer)root.EvaluateExpression() !).Query.Expression;
                root = root.SkipMethodChain(builder.MappingSchema);
            }

            root = builder.ConvertExpressionTree(root);

            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, root)
            {
                CreateSubQuery = true
            });

            var finalFunction = functions.First();

            var sqlExpression = finalFunction.GetExpression(builder.DataContext, buildInfo.SelectQuery, methodCall,
                                                            (e, descriptor) => builder.ConvertToExtensionSql(sequence, e, descriptor));

            var context = new ChainContext(buildInfo.Parent, sequence, methodCall);

            context.Sql        = context.SelectQuery;
            context.FieldIndex = context.SelectQuery.Select.Add(sqlExpression, methodCall.Method.Name);

            return(context);
        }
Exemple #2
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var functions = Sql.ExtensionAttribute.GetExtensionAttributes(methodCall, builder.MappingSchema);

            var           chain    = Sql.ExtensionAttribute.BuildFunctionsChain(builder.MappingSchema, methodCall);
            IBuildContext sequence = null;

            foreach (var expression in chain)
            {
                if (expression is MethodCallExpression mc)
                {
                    if (mc.Arguments.Count > 0)
                    {
                        if (typeof(IEnumerable <>).IsSameOrParentOf(mc.Arguments[0].Type))
                        {
                            sequence = builder.BuildSequence(new BuildInfo(buildInfo, mc.Arguments[0])
                            {
                                IsChain = true
                            });
                        }
                        else if (typeof(Sql.IQueryableContainer).IsSameOrParentOf(mc.Arguments[0].Type))
                        {
                            sequence = builder.BuildSequence(new BuildInfo(buildInfo,
                                                                           ((Sql.IQueryableContainer)mc.Arguments[0].EvaluateExpression()).Query.Expression)
                            {
                                IsChain = true
                            });
                        }
                    }
                }
            }

            if (sequence == null)
            {
                throw new LinqToDBException($"{methodCall} can not be converted to SQL.");
            }

            if (buildInfo.IsChain)
            {
                // it means that function is just sequence provider
                return(sequence);
            }

            var finalFunction = functions.First();

            var sqlExpression = finalFunction.GetExpression(builder.DataContext, buildInfo.SelectQuery, methodCall,
                                                            e => builder.ConvertToExtensionSql(sequence, e));

            var context = new ChainContext(buildInfo.Parent, sequence, methodCall);

            context.Sql        = context.SelectQuery;
            context.FieldIndex = context.SelectQuery.Select.Add(sqlExpression, methodCall.Method.Name);

            return(context);
        }