示例#1
0
            public TableContext(ExpressionBuilder builder, BuildInfo buildInfo)
            {
                Builder     = builder;
                Parent      = buildInfo.Parent;
                Expression  = buildInfo.Expression;
                SelectQuery = buildInfo.SelectQuery;

                var mc   = (MethodCallExpression)Expression;
                var attr = builder.GetTableFunctionAttribute(mc.Method);

                if (!typeof(ITable <>).IsSameOrParentOf(mc.Method.ReturnType))
                {
                    throw new LinqException("Table function has to return Table<T>.");
                }

                OriginalType     = mc.Method.ReturnType.GetGenericArgumentsEx()[0];
                ObjectType       = GetObjectType();
                SqlTable         = new SqlTable(builder.MappingSchema, ObjectType);
                EntityDescriptor = Builder.MappingSchema.GetEntityDescriptor(ObjectType);

                SelectQuery.From.Table(SqlTable);

                var args = mc.Arguments.Select(a => builder.ConvertToSql(this, a));

                attr.SetTable(SqlTable, mc.Method, mc.Arguments, args);

                Init();
            }
示例#2
0
        static T Find <T>(ExpressionBuilder builder, BuildInfo buildInfo, Func <int, IBuildContext, T> action)
        {
            var expression = buildInfo.Expression;

            switch (expression.NodeType)
            {
            case ExpressionType.Constant:
            {
                var c = (ConstantExpression)expression;
                if (c.Value is IQueryable)
                {
                    return(action(1, null));
                }

                break;
            }

            case ExpressionType.Call:
            {
                var mc = (MethodCallExpression)expression;

                if (mc.Method.Name == "GetTable")
                {
                    if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                    {
                        return(action(2, null));
                    }
                }

                var attr = builder.GetTableFunctionAttribute(mc.Method);

                if (attr != null)
                {
                    return(action(5, null));
                }

                break;
            }

            case ExpressionType.MemberAccess:

                if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                {
                    return(action(3, null));
                }

                // Looking for association.
                //
                if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0)
                {
                    var ctx = builder.GetContext(buildInfo.Parent, expression);
                    if (ctx != null)
                    {
                        return(action(4, ctx));
                    }
                }

                break;

            case ExpressionType.Parameter:
            {
                if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0)
                {
                    var ctx = builder.GetContext(buildInfo.Parent, expression);
                    if (ctx != null)
                    {
                        return(action(4, ctx));
                    }
                }

                break;
            }
            }

            return(action(0, null));
        }
示例#3
0
        static BuildContextType FindBuildContext(ExpressionBuilder builder, BuildInfo buildInfo, out IBuildContext?parentContext)
        {
            parentContext = null;

            var expression = buildInfo.Expression;

            switch (expression.NodeType)
            {
            case ExpressionType.Constant:
            {
                var c = (ConstantExpression)expression;

                if (c.Value is IQueryable queryable)
                {
                    if (typeof(CteTable <>).IsSameOrParentOf(c.Value.GetType()))
                    {
                        return(BuildContextType.CteConstant);
                    }

                    // Avoid collision with ArrayBuilder
                    var elementType = queryable.ElementType;
                    if (builder.MappingSchema.IsScalarType(elementType) && typeof(EnumerableQuery <>).IsSameOrParentOf(c.Value.GetType()))
                    {
                        break;
                    }

                    if (queryable.Expression.NodeType == ExpressionType.NewArrayInit)
                    {
                        break;
                    }

                    return(BuildContextType.TableConstant);
                }

                break;
            }

            case ExpressionType.Call:
            {
                var mc = (MethodCallExpression)expression;

                switch (mc.Method.Name)
                {
                case "GetTable":
                {
                    if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                    {
                        return(BuildContextType.GetTableMethod);
                    }
                    break;
                }

                case "AsCte":
                    return(BuildContextType.AsCteMethod);

                case "FromSql":
                    return(BuildContextType.FromSqlMethod);

                case "FromSqlScalar":
                    return(BuildContextType.FromSqlScalarMethod);
                }

                var attr = builder.GetTableFunctionAttribute(mc.Method);

                if (attr != null)
                {
                    return(BuildContextType.TableFunctionAttribute);
                }

                if (mc.IsAssociation(builder.MappingSchema))
                {
                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;
            }

            case ExpressionType.MemberAccess:

                if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                {
                    return(BuildContextType.MemberAccess);
                }

                // Looking for association.
                //
                if (buildInfo.IsSubQuery /* && buildInfo.SelectQuery.From.Tables.Count == 0*/)
                {
                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;

            case ExpressionType.Parameter:
            {
                if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0)
                {
                    // It should be handled by GroupByElementBuilder
                    //
                    if (typeof(IGrouping <,>).IsSameOrParentOf(expression.Type))
                    {
                        break;
                    }

                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;
            }
            }

            return(BuildContextType.None);
        }
示例#4
0
        static BuildContextType FindBuildContext(ExpressionBuilder builder, BuildInfo buildInfo, out IBuildContext parentContext)
        {
            parentContext = null;

            var expression = buildInfo.Expression;

            switch (expression.NodeType)
            {
            case ExpressionType.Constant:
            {
                var c = (ConstantExpression)expression;

                if (c.Value is IQueryable)
                {
                    if (typeof(CteTable <>).IsSameOrParentOf(c.Value.GetType()))
                    {
                        return(BuildContextType.CteConstant);
                    }

                    return(BuildContextType.TableConstant);
                }

                break;
            }

            case ExpressionType.Call:
            {
                var mc = (MethodCallExpression)expression;

                switch (mc.Method.Name)
                {
                case "GetTable":
                    if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                    {
                        return(BuildContextType.GetTableMethod);
                    }
                    break;

                case "AsCte":
                    return(BuildContextType.AsCteMethod);
                }

                var attr = builder.GetTableFunctionAttribute(mc.Method);

                if (attr != null)
                {
                    return(BuildContextType.TableFunctionAttribute);
                }

                if (mc.IsAssociation(builder.MappingSchema))
                {
                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;
            }

            case ExpressionType.MemberAccess:

                if (typeof(ITable <>).IsSameOrParentOf(expression.Type))
                {
                    return(BuildContextType.MemberAccess);
                }

                // Looking for association.
                //
                if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0)
                {
                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;

            case ExpressionType.Parameter:
            {
                if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0)
                {
                    parentContext = builder.GetContext(buildInfo.Parent, expression);
                    if (parentContext != null)
                    {
                        return(BuildContextType.Association);
                    }
                }

                break;
            }
            }

            return(BuildContextType.None);
        }