internal QueryInfo[] BuildQuery(Expression query, SqlNodeAnnotations annotations) { this.CheckDispose(); // apply maximal funcletization query = Funcletizer.Funcletize(query); // convert query nodes into sql nodes QueryConverter converter = new QueryConverter(_services, _typeProvider, _translator, _sqlFactory); switch(this.Mode) { case SqlServerProviderMode.Sql2000: converter.ConverterStrategy = ConverterStrategy.CanUseScopeIdentity | ConverterStrategy.CanUseJoinOn | ConverterStrategy.CanUseRowStatus; break; case SqlServerProviderMode.Sql2005: case SqlServerProviderMode.Sql2008: converter.ConverterStrategy = ConverterStrategy.CanUseScopeIdentity | ConverterStrategy.SkipWithRowNumber | ConverterStrategy.CanUseRowStatus | ConverterStrategy.CanUseJoinOn | ConverterStrategy.CanUseOuterApply | ConverterStrategy.CanOutputFromInsert; break; case SqlServerProviderMode.SqlCE: converter.ConverterStrategy = ConverterStrategy.CanUseOuterApply; // Can't set ConverterStrategy.CanUseJoinOn because scalar subqueries in the ON clause // can't be converted into anything. break; } SqlNode node = converter.ConvertOuter(query); return this.BuildQuery(this.GetResultShape(query), this.GetResultType(query), node, null, annotations); }
internal SqlNode TranslateLink(SqlLink link, List<SqlExpression> keyExpressions, bool asExpression) { MetaDataMember mm = link.Member; if (mm.IsAssociation) { // Create the row source. MetaType otherType = mm.Association.OtherType; Type tableType = otherType.InheritanceRoot.Type; ITable table = this.services.Context.GetTable(tableType); Expression source = new LinkedTableExpression(link, table, typeof(IQueryable<>).MakeGenericType(otherType.Type)); // Build key expression nodes. Expression[] keyExprs = new Expression[keyExpressions.Count]; for (int i = 0; i < keyExpressions.Count; ++i) { MetaDataMember metaMember = mm.Association.OtherKey[i]; Type memberType = TypeSystem.GetMemberType(metaMember.Member); keyExprs[i] = InternalExpression.Known(keyExpressions[i], memberType); } Expression lex = link.Expression != null ? (Expression)InternalExpression.Known(link.Expression) : (Expression)Expression.Constant(null, link.Member.Member.DeclaringType); Expression expr = TranslateAssociation(this.services.Context, mm.Association, source, keyExprs, lex); // Convert QueryConverter qc = new QueryConverter(this.services, this.typeProvider, this, this.sql); SqlSelect sel = (SqlSelect)qc.ConvertInner(expr, link.SourceExpression); // Turn it into an expression is necessary SqlNode result = sel; if (asExpression) { if (mm.Association.IsMany) { result = new SqlSubSelect(SqlNodeType.Multiset, link.ClrType, link.SqlType, sel); } else { result = new SqlSubSelect(SqlNodeType.Element, link.ClrType, link.SqlType, sel); } } return result; } else { System.Diagnostics.Debug.Assert(link.Expansion != null); System.Diagnostics.Debug.Assert(link.KeyExpressions == keyExpressions); // deferred expression already defined... return link.Expansion; } }