Esempio n. 1
0
        static void BuildTake(ExpressionBuilder builder, IBuildContext sequence, ISqlExpression expr)
        {
            var sql = sequence.SelectQuery;

            sql.Select.Take(expr);

            if (sql.Select.SkipValue != null &&
                builder.DataContextInfo.SqlProviderFlags.IsTakeSupported &&
                !builder.DataContextInfo.SqlProviderFlags.GetIsSkipSupportedFlag(sql))
            {
                if (sql.Select.SkipValue is SqlParameter && sql.Select.TakeValue is SqlValue)
                {
                    var skip = (SqlParameter)sql.Select.SkipValue;
                    var parm = (SqlParameter)sql.Select.SkipValue.Clone(new Dictionary <ICloneableElement, ICloneableElement>(), _ => true);

                    parm.SetTakeConverter((int)((SqlValue)sql.Select.TakeValue).Value);

                    sql.Select.Take(parm);

                    var ep = (from pm in builder.CurrentSqlParameters where pm.SqlParameter == skip select pm).First();

                    ep = new ParameterAccessor
                    {
                        Expression   = ep.Expression,
                        Accessor     = ep.Accessor,
                        SqlParameter = parm
                    };

                    builder.CurrentSqlParameters.Add(ep);
                }
                else
                {
                    sql.Select.Take(builder.Convert(
                                        sequence,
                                        new SqlBinaryExpression(typeof(int), sql.Select.SkipValue, "+", sql.Select.TakeValue, Precedence.Additive)));
                }
            }

            if (!builder.DataContextInfo.SqlProviderFlags.GetAcceptsTakeAsParameterFlag(sql))
            {
                var p = sql.Select.TakeValue as SqlParameter;

                if (p != null)
                {
                    p.IsQueryParameter = false;
                }
            }
        }
            private void BuildAssociationCondition(ExpressionBuilder builder, TableContext parent, AssociationDescriptor association, SqlSearchCondition condition)
            {
                for (var i = 0; i < association.ThisKey.Length; i++)
                {
                    if (!parent.SqlTable.Fields.TryGetValue(association.ThisKey[i], out var field1))
                    {
                        throw new LinqException("Association key '{0}' not found for type '{1}.", association.ThisKey[i], parent.ObjectType);
                    }

                    if (!SqlTable.Fields.TryGetValue(association.OtherKey[i], out var field2))
                    {
                        throw new LinqException("Association key '{0}' not found for type '{1}.", association.OtherKey[i], ObjectType);
                    }

                    ISqlPredicate predicate = new SqlPredicate.ExprExpr(
                        field1, SqlPredicate.Operator.Equal, field2);

                    predicate = builder.Convert(parent, predicate);

                    condition.Conditions.Add(new SqlCondition(false, predicate));
                }

                if (ObjectType != OriginalType)
                {
                    var predicate = Builder.MakeIsPredicate(this, OriginalType);

                    if (predicate.GetType() != typeof(SqlPredicate.Expr))
                    {
                        condition.Conditions.Add(new SqlCondition(false, predicate));
                    }
                }

                RegularConditionCount = condition.Conditions.Count;
                ExpressionPredicate   = Association.GetPredicate(parent.ObjectType, ObjectType);

                if (ExpressionPredicate != null)
                {
                    ExpressionPredicate = (LambdaExpression)Builder.ConvertExpressionTree(ExpressionPredicate);

                    var expr = Builder.ConvertExpression(ExpressionPredicate.Body.Unwrap());

                    Builder.BuildSearchCondition(
                        new ExpressionContext(parent.Parent, new IBuildContext[] { parent, this }, ExpressionPredicate),
                        expr,
                        condition.Conditions,
                        false);
                }
            }
Esempio n. 3
0
        static void BuildSubQueryJoin(
            ExpressionBuilder builder,
            IBuildContext outerKeyContext, Expression outerKeySelector,
            Expression innerKeySelector,
            IBuildContext subQueryKeyContext, SelectQuery subQuerySelect)
        {
            var predicate = builder.ConvertObjectComparison(
                ExpressionType.Equal,
                outerKeyContext, outerKeySelector,
                subQueryKeyContext, innerKeySelector);

            if (predicate == null)
            {
                predicate = new SqlPredicate.ExprExpr(
                    builder.ConvertToSql(outerKeyContext, outerKeySelector),
                    SqlPredicate.Operator.Equal,
                    builder.ConvertToSql(subQueryKeyContext, innerKeySelector));

                predicate = builder.Convert(outerKeyContext, predicate);
            }

            subQuerySelect.Where.SearchCondition.Conditions.Add(new SqlCondition(false, predicate));
        }
Esempio n. 4
0
        internal static void BuildJoin(
            ExpressionBuilder builder,
            SqlSearchCondition condition,
            IBuildContext outerKeyContext, Expression outerKeySelector,
            IBuildContext innerKeyContext, Expression innerKeySelector)
        {
            var predicate = builder.ConvertObjectComparison(
                ExpressionType.Equal,
                outerKeyContext, outerKeySelector,
                innerKeyContext, innerKeySelector);

            if (predicate == null)
            {
                predicate = new SqlPredicate.ExprExpr(
                    builder.ConvertToSql(outerKeyContext, outerKeySelector),
                    SqlPredicate.Operator.Equal,
                    builder.ConvertToSql(innerKeyContext, innerKeySelector));

                predicate = builder.Convert(outerKeyContext, predicate);
            }

            condition.Conditions.Add(new SqlCondition(false, predicate));
        }
Esempio n. 5
0
		static void BuildJoin(
			ExpressionBuilder builder,
			SelectQuery.FromClause.Join join,
			IBuildContext outerKeyContext, Expression outerKeySelector,
			IBuildContext innerKeyContext, Expression innerKeySelector)
		{
			var predicate = builder.ConvertObjectComparison(
				ExpressionType.Equal,
				outerKeyContext, outerKeySelector,
				innerKeyContext, innerKeySelector);

			if (predicate == null)
			{
				predicate = new SelectQuery.Predicate.ExprExpr(
					builder.ConvertToSql(outerKeyContext, outerKeySelector),
					SelectQuery.Predicate.Operator.Equal,
					builder.ConvertToSql(innerKeyContext, innerKeySelector));

				predicate = builder.Convert(outerKeyContext, predicate);
			}

			join.JoinedTable.Condition.Conditions.Add(new SelectQuery.Condition(false, predicate));
		}
            public AssociatedTableContext(
                [JetBrains.Annotations.NotNull] ExpressionBuilder builder,
                [JetBrains.Annotations.NotNull] TableContext parent,
                [JetBrains.Annotations.NotNull] AssociationDescriptor association
                )
                : base(builder, parent.SelectQuery)
            {
                if (builder == null)
                {
                    throw new ArgumentNullException(nameof(builder));
                }
                if (parent == null)
                {
                    throw new ArgumentNullException(nameof(parent));
                }
                if (association == null)
                {
                    throw new ArgumentNullException(nameof(association));
                }

                var type = association.MemberInfo.GetMemberType();
                var left = association.CanBeNull;

                if (typeof(IEnumerable).IsSameOrParentOf(type))
                {
                    var eTypes = type.GetGenericArguments(typeof(IEnumerable <>));
                    type   = eTypes != null && eTypes.Length > 0 ? eTypes[0] : type.GetListItemType();
                    IsList = true;
                }

                OriginalType       = type;
                ObjectType         = GetObjectType();
                EntityDescriptor   = Builder.MappingSchema.GetEntityDescriptor(ObjectType);
                InheritanceMapping = EntityDescriptor.InheritanceMapping;
                SqlTable           = new SqlTable(builder.MappingSchema, ObjectType);

                Association       = association;
                ParentAssociation = parent;

                SqlJoinedTable join;

                var queryMethod = Association.GetQueryMethod(parent.ObjectType, ObjectType);

                if (queryMethod != null)
                {
                    var dcParam     = queryMethod.Parameters[1];
                    var resultParam = Expression.Parameter(ObjectType);

                    Expression dcConst = Expression.Constant(builder.DataContext);
                    if (dcParam.Type != typeof(IDataContext))
                    {
                        dcConst = Expression.Convert(dcConst, dcParam.Type);
                    }

                    var body = queryMethod.Body.Transform(e => e == dcParam ? dcConst : e);
                    body        = Expression.Convert(body, typeof(IEnumerable <>).MakeGenericType(ObjectType));
                    queryMethod = Expression.Lambda(body, queryMethod.Parameters[0]);

                    var selectManyMethodInfo = _selectManyMethodInfo.MakeGenericMethod(parent.ObjectType, ObjectType, ObjectType);
                    var resultLamba          = Expression.Lambda(resultParam, Expression.Parameter(parent.ObjectType), resultParam);
                    var selectManyMethod     = Expression.Call(null, selectManyMethodInfo, parent.Expression, queryMethod, resultLamba);
                    var ownerTableSource     = SelectQuery.From.Tables[0];

                    _innerContext = builder.BuildSequence(new BuildInfo(this, selectManyMethod, new SelectQuery())
                    {
                        IsAssociationBuilt = true
                    });

                    var associationQuery = _innerContext.SelectQuery;

                    if (associationQuery.Select.From.Tables.Count < 1)
                    {
                        throw new LinqToDBException("Invalid association query. It is not possible to inline query.");
                    }

                    var foundIndex = associationQuery.Select.From.Tables.FindIndex(t =>
                                                                                   t.Source is SqlTable sqlTable && QueryHelper.IsEqualTables(sqlTable, parent.SqlTable));

                    if (foundIndex < 0)
                    {
                        throw new LinqToDBException("Invalid association query. It is not possible to inline query. Can not find owner table.");
                    }

                    var sourceToReplace = associationQuery.Select.From.Tables[foundIndex];

                    if (left)
                    {
                        foreach (var joinedTable in sourceToReplace.Joins)
                        {
                            if (joinedTable.JoinType == JoinType.Inner)
                            {
                                joinedTable.JoinType = JoinType.Left;
                            }
                            else if (joinedTable.JoinType == JoinType.CrossApply)
                            {
                                joinedTable.JoinType = JoinType.OuterApply;
                            }

                            joinedTable.IsWeak = true;
                        }
                    }

                    ownerTableSource.Joins.AddRange(sourceToReplace.Joins);

                    // prepare fields mapping to replace fields that will be generated by association query
                    _replaceMap =
                        ((SqlTable)sourceToReplace.Source).Fields.Values.ToDictionary(f => (ISqlExpression)f,
                                                                                      f => parent.SqlTable.Fields[f.Name]);

                    ownerTableSource.Walk(false, e =>
                    {
                        if (_replaceMap.TryGetValue(e, out var newField))
                        {
                            return(newField);
                        }
                        return(e);
                    });

                    ParentAssociationJoin = sourceToReplace.Joins.FirstOrDefault();
                    join = ParentAssociationJoin;

                    // add rest of tables
                    SelectQuery.From.Tables.AddRange(associationQuery.Select.From.Tables.Where(t => t != sourceToReplace));
                }
                else
                {
                    var psrc = parent.SelectQuery.From[parent.SqlTable];
                    join = left ? SqlTable.WeakLeftJoin().JoinedTable : SqlTable.WeakInnerJoin().JoinedTable;

                    ParentAssociationJoin = join;

                    psrc.Joins.Add(join);

                    for (var i = 0; i < association.ThisKey.Length; i++)
                    {
                        if (!parent.SqlTable.Fields.TryGetValue(association.ThisKey[i], out var field1))
                        {
                            throw new LinqException("Association key '{0}' not found for type '{1}.", association.ThisKey[i], parent.ObjectType);
                        }

                        if (!SqlTable.Fields.TryGetValue(association.OtherKey[i], out var field2))
                        {
                            throw new LinqException("Association key '{0}' not found for type '{1}.", association.OtherKey[i], ObjectType);
                        }

                        //					join.Field(field1).Equal.Field(field2);

                        ISqlPredicate predicate = new SqlPredicate.ExprExpr(
                            field1, SqlPredicate.Operator.Equal, field2);

                        predicate = builder.Convert(parent, predicate);

                        join.Condition.Conditions.Add(new SqlCondition(false, predicate));
                    }

                    if (ObjectType != OriginalType)
                    {
                        var predicate = Builder.MakeIsPredicate(this, OriginalType);

                        if (predicate.GetType() != typeof(SqlPredicate.Expr))
                        {
                            join.Condition.Conditions.Add(new SqlCondition(false, predicate));
                        }
                    }

                    RegularConditionCount = join.Condition.Conditions.Count;
                    ExpressionPredicate   = Association.GetPredicate(parent.ObjectType, ObjectType);

                    if (ExpressionPredicate != null)
                    {
                        ExpressionPredicate = (LambdaExpression)Builder.ConvertExpressionTree(ExpressionPredicate);

                        var expr = Builder.ConvertExpression(ExpressionPredicate.Body.Unwrap());

                        Builder.BuildSearchCondition(
                            new ExpressionContext(parent.Parent, new IBuildContext[] { parent, this }, ExpressionPredicate),
                            expr,
                            join.Condition.Conditions,
                            false);
                    }
                }

                if (!association.AliasName.IsNullOrEmpty() && join != null)
                {
                    join.Table.Alias = association.AliasName;
                }
                else
                {
                    if (!Common.Configuration.Sql.AssociationAlias.IsNullOrEmpty() && join != null)
                    {
                        join.Table.Alias = string.Format(Common.Configuration.Sql.AssociationAlias,
                                                         association.MemberInfo.Name);
                    }
                }

                Init(false);
            }
            public AssociatedTableContext(
                [JetBrains.Annotations.NotNull] ExpressionBuilder builder,
                [JetBrains.Annotations.NotNull] TableContext parent,
                [JetBrains.Annotations.NotNull] AssociationDescriptor association
                )
                : base(builder, parent.SelectQuery)
            {
                if (builder == null)
                {
                    throw new ArgumentNullException(nameof(builder));
                }
                if (parent == null)
                {
                    throw new ArgumentNullException(nameof(parent));
                }
                if (association == null)
                {
                    throw new ArgumentNullException(nameof(association));
                }

                var type = association.MemberInfo.GetMemberType();
                var left = association.CanBeNull;

                if (typeof(IEnumerable).IsSameOrParentOf(type))
                {
                    var eTypes = type.GetGenericArguments(typeof(IEnumerable <>));
                    type   = eTypes != null && eTypes.Length > 0 ? eTypes[0] : type.GetListItemType();
                    IsList = true;
                }

                OriginalType       = type;
                ObjectType         = GetObjectType();
                EntityDescriptor   = Builder.MappingSchema.GetEntityDescriptor(ObjectType);
                InheritanceMapping = EntityDescriptor.InheritanceMapping;
                SqlTable           = new SqlTable(builder.MappingSchema, ObjectType);

                var psrc = parent.SelectQuery.From[parent.SqlTable];
                var join = left ? SqlTable.WeakLeftJoin() : SqlTable.WeakInnerJoin();

                if (!association.AliasName.IsNullOrEmpty())
                {
                    join.JoinedTable.Table.Alias = association.AliasName;
                }
                else
                {
                    if (!Common.Configuration.Sql.AssociationAlias.IsNullOrEmpty())
                    {
                        join.JoinedTable.Table.Alias = string.Format(Common.Configuration.Sql.AssociationAlias,
                                                                     association.MemberInfo.Name);
                    }
                }

                Association           = association;
                ParentAssociation     = parent;
                ParentAssociationJoin = join.JoinedTable;

                psrc.Joins.Add(join.JoinedTable);

                for (var i = 0; i < association.ThisKey.Length; i++)
                {
                    if (!parent.SqlTable.Fields.TryGetValue(association.ThisKey[i], out var field1))
                    {
                        throw new LinqException("Association key '{0}' not found for type '{1}.", association.ThisKey[i], parent.ObjectType);
                    }

                    if (!SqlTable.Fields.TryGetValue(association.OtherKey[i], out var field2))
                    {
                        throw new LinqException("Association key '{0}' not found for type '{1}.", association.OtherKey[i], ObjectType);
                    }

//					join.Field(field1).Equal.Field(field2);

                    ISqlPredicate predicate = new SqlPredicate.ExprExpr(
                        field1, SqlPredicate.Operator.Equal, field2);

                    predicate = builder.Convert(parent, predicate);

                    join.JoinedTable.Condition.Conditions.Add(new SqlCondition(false, predicate));
                }

                if (ObjectType != OriginalType)
                {
                    var predicate = Builder.MakeIsPredicate(this, OriginalType);

                    if (predicate.GetType() != typeof(SqlPredicate.Expr))
                    {
                        join.JoinedTable.Condition.Conditions.Add(new SqlCondition(false, predicate));
                    }
                }

                RegularConditionCount = join.JoinedTable.Condition.Conditions.Count;
                ExpressionPredicate   = Association.GetPredicate(parent.ObjectType, ObjectType);

                if (ExpressionPredicate != null)
                {
                    ExpressionPredicate = (LambdaExpression)Builder.ConvertExpressionTree(ExpressionPredicate);

                    var expr = Builder.ConvertExpression(ExpressionPredicate.Body.Unwrap());

                    Builder.BuildSearchCondition(
                        new ExpressionContext(parent.Parent, new IBuildContext[] { parent, this }, ExpressionPredicate),
                        expr,
                        join.JoinedTable.Condition.Conditions,
                        false);
                }

                Init(false);
            }