internal static SelectExpression SelectAndFirstDatabaseExpressions(AdventureWorks adventureWorks) { QueryCompilationContext compilationContext = adventureWorks.GetService <IQueryCompilationContextFactory>() .Create(async: false); SelectExpression selectExpression = new SelectExpression( dependencies: new SelectExpressionDependencies(adventureWorks.GetService <IQuerySqlGeneratorFactory>(), adventureWorks.GetService <IRelationalTypeMappingSource>()), queryCompilationContext: (RelationalQueryCompilationContext)compilationContext); MainFromClause querySource = new MainFromClause( itemName: "product", itemType: typeof(Product), fromExpression: Expression.Constant(adventureWorks.ProductCategories)); TableExpression tableExpression = new TableExpression( table: nameof(Product), schema: AdventureWorks.Production, alias: querySource.ItemName, querySource: querySource); selectExpression.AddTable(tableExpression); IEntityType productEntityType = adventureWorks.Model.FindEntityType(typeof(Product)); IProperty nameProperty = productEntityType.FindProperty(nameof(Product.Name)); selectExpression.AddToProjection(new ColumnExpression( name: nameof(Product.Name), property: nameProperty, tableExpression: tableExpression)); selectExpression.Limit = Expression.Constant(1); return(selectExpression.WriteLine()); }
private JoinExpressionBase AdjustJoinExpression( SelectExpression selectExpression, JoinExpressionBase joinExpression) { var subquery = new SelectExpression(_querySqlGeneratorFactory, _queryCompilationContext) { Alias = joinExpression.Alias }; // Don't create new alias when adding tables to subquery subquery.AddTable(joinExpression.TableExpression, createUniqueAlias: false); subquery.ProjectStarAlias = joinExpression.Alias; subquery.IsProjectStar = true; subquery.Predicate = selectExpression.Predicate; var newJoinExpression = joinExpression is LeftOuterJoinExpression ? (JoinExpressionBase) new LeftOuterJoinExpression(subquery) : new InnerJoinExpression(subquery); newJoinExpression.QuerySource = joinExpression.QuerySource; newJoinExpression.Alias = joinExpression.Alias; return(newJoinExpression); }
protected override Expression VisitEntityQueryable(Type elementType) { var relationalQueryCompilationContext = ((RelationalQueryCompilationContext)QueryCompilationContext); var queryMethodInfo = CreateValueReaderMethodInfo; var entityType = QueryCompilationContext.Model.GetEntityType(elementType); var selectExpression = new SelectExpression(); selectExpression .AddTable( new TableExpression( entityType.TableName(), entityType.Schema(), _querySource.ItemName.Replace("<generated>_", "t"), _querySource)); _queryModelVisitor._queriesBySource.Add(_querySource, selectExpression); var queryMethodArguments = new List <Expression> { Expression.Constant(_querySource), QueryContextParameter, QuerySourceScopeParameter, _readerParameter }; if (_queryModelVisitor.QuerySourceRequiresMaterialization(_querySource)) { foreach (var property in entityType.Properties) { selectExpression.AddToProjection(property, _querySource); } queryMethodInfo = CreateEntityMethodInfo.MakeGenericMethod(elementType); queryMethodArguments.Add(Expression.Constant(0)); } return(Expression.Call( relationalQueryCompilationContext.QueryMethodProvider.QueryMethod .MakeGenericMethod(queryMethodInfo.ReturnType), QueryContextParameter, Expression.Constant(new CommandBuilder(selectExpression, relationalQueryCompilationContext)), Expression.Lambda( Expression.Call(queryMethodInfo, queryMethodArguments), _readerParameter))); }
private IEnumerable <Expression> CreateIncludeRelatedValuesStrategyFactories( IQuerySource querySource, IEnumerable <INavigation> navigationPath) { var selectExpression = _queryCompilationContext.FindSelectExpression(querySource); var targetTableExpression = selectExpression.FindTableForQuerySource(querySource); var readerIndex = 0; foreach (var navigation in navigationPath) { if (!navigation.IsCollection()) { var targetEntityType = navigation.GetTargetType(); var targetTableName = _queryCompilationContext.GetTableName(targetEntityType); var targetTableAlias = targetTableName.First().ToString().ToLower(); var joinedTableExpression = new TableExpression( targetTableName, _queryCompilationContext.GetSchema(targetEntityType), targetTableAlias, querySource); var readerOffset = selectExpression.Projection.Count; var columnExpressions = targetEntityType.Properties .Select(p => new ColumnExpression( _queryCompilationContext.GetColumnName(p), p, joinedTableExpression)); var joinExpression = navigation.ForeignKey.IsRequired && navigation.PointsToPrincipal ? selectExpression .AddInnerJoin(joinedTableExpression, columnExpressions) : selectExpression .AddOuterJoin(joinedTableExpression, columnExpressions); joinExpression.Predicate = BuildJoinEqualityExpression( navigation, (navigation.PointsToPrincipal ? targetEntityType : navigation.EntityType) .GetPrimaryKey().Properties, navigation.PointsToPrincipal ? targetTableExpression : joinExpression, navigation.PointsToPrincipal ? joinExpression : targetTableExpression); targetTableExpression = joinedTableExpression; yield return (Expression.Lambda( Expression.Call( _queryCompilationContext.QueryMethodProvider .CreateReferenceIncludeRelatedValuesStrategyMethod, Expression.Convert(EntityQueryModelVisitor.QueryContextParameter, typeof(RelationalQueryContext)), Expression.Constant(readerIndex), Expression.Constant(readerOffset)))); } else { var principalTable = selectExpression.Tables.Last(t => t.QuerySource == querySource); foreach (var property in navigation.EntityType.GetPrimaryKey().Properties) { selectExpression .AddToOrderBy( _queryCompilationContext.GetColumnName(property), property, principalTable, OrderingDirection.Asc); } var targetEntityType = navigation.GetTargetType(); var targetTableName = _queryCompilationContext.GetTableName(targetEntityType); var targetTableAlias = targetTableName.First().ToString().ToLower(); var targetSelectExpression = new SelectExpression(); targetTableExpression = new TableExpression( targetTableName, _queryCompilationContext.GetSchema(targetEntityType), targetTableAlias, querySource); targetSelectExpression.AddTable(targetTableExpression); foreach (var property in targetEntityType.Properties) { targetSelectExpression .AddToProjection( _queryCompilationContext.GetColumnName(property), property, querySource); } var innerJoinSelectExpression = selectExpression.Clone( ((ColumnExpression)selectExpression.OrderBy.Last().Expression).TableAlias); innerJoinSelectExpression.IsDistinct = true; innerJoinSelectExpression.ClearProjection(); foreach (var columnExpression in innerJoinSelectExpression.OrderBy .Select(o => o.Expression) .Cast <ColumnExpression>()) { innerJoinSelectExpression.AddToProjection(columnExpression); } innerJoinSelectExpression.ClearOrderBy(); var primaryKeyProperties = navigation.EntityType.GetPrimaryKey().Properties; var innerJoinExpression = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression); foreach (var ordering in selectExpression.OrderBy) { var columnExpression = (ColumnExpression)ordering.Expression; targetSelectExpression .AddToOrderBy( columnExpression.Name, columnExpression.Property, innerJoinExpression, ordering.OrderingDirection); } innerJoinExpression.Predicate = BuildJoinEqualityExpression( navigation, primaryKeyProperties, targetTableExpression, innerJoinExpression); var readerParameter = Expression.Parameter(typeof(DbDataReader)); selectExpression = targetSelectExpression; readerIndex++; yield return (Expression.Lambda( Expression.Call( _queryCompilationContext.QueryMethodProvider .CreateCollectionIncludeRelatedValuesStrategyMethod, Expression.Call( _queryCompilationContext.QueryMethodProvider.QueryMethod .MakeGenericMethod(typeof(IValueReader)), EntityQueryModelVisitor.QueryContextParameter, Expression.Constant(new CommandBuilder(targetSelectExpression, _queryCompilationContext)), Expression.Lambda( Expression.Call( _createValueReaderForIncludeMethodInfo, EntityQueryModelVisitor.QueryContextParameter, readerParameter, Expression.Constant(targetEntityType)), readerParameter))))); } } }
protected override Expression VisitEntityQueryable([NotNull] Type elementType) { Check.NotNull(elementType, nameof(elementType)); var queryMethodInfo = RelationalQueryModelVisitor.CreateValueReaderMethodInfo; var entityType = QueryModelVisitor.QueryCompilationContext.Model.GetEntityType(elementType); var selectExpression = new SelectExpression(); var tableName = QueryModelVisitor.QueryCompilationContext.GetTableName(entityType); var alias = _querySource.ItemName.StartsWith("<generated>_") ? tableName.First().ToString().ToLower() : _querySource.ItemName; var fromSqlAnnotation = GetAnnotations <FromSqlAnnotation>(_querySource).SingleOrDefault(); selectExpression.AddTable( (fromSqlAnnotation != null) ? (TableExpressionBase) new RawSqlDerivedTableExpression( fromSqlAnnotation.Sql, fromSqlAnnotation.Parameters, alias, _querySource) : new TableExpression( tableName, QueryModelVisitor.QueryCompilationContext.GetSchema(entityType), alias, _querySource)); QueryModelVisitor.AddQuery(_querySource, selectExpression); var queryMethodArguments = new List <Expression> { Expression.Constant(_querySource), EntityQueryModelVisitor.QueryContextParameter, EntityQueryModelVisitor.QuerySourceScopeParameter, _readerParameter }; if (QueryModelVisitor.QuerySourceRequiresMaterialization(_querySource)) { var materializer = new MaterializerFactory( QueryModelVisitor .QueryCompilationContext .EntityMaterializerSource) .CreateMaterializer( entityType, selectExpression, (p, se) => se.AddToProjection( QueryModelVisitor.QueryCompilationContext.GetColumnName(p), p, _querySource), _querySource); queryMethodInfo = RelationalQueryModelVisitor.CreateEntityMethodInfo .MakeGenericMethod(elementType); var keyProperties = entityType.GetPrimaryKey().Properties; var keyFactory = QueryModelVisitor.QueryCompilationContext.EntityKeyFactorySource .GetKeyFactory(keyProperties); queryMethodArguments.AddRange( new[] { Expression.Constant(0), Expression.Constant(entityType), Expression.Constant(QueryModelVisitor.QuerySourceRequiresTracking(_querySource)), Expression.Constant(keyFactory), Expression.Constant(keyProperties), materializer }); } return(Expression.Call( QueryModelVisitor.QueryCompilationContext.QueryMethodProvider.QueryMethod .MakeGenericMethod(queryMethodInfo.ReturnType), EntityQueryModelVisitor.QueryContextParameter, Expression.Constant(new CommandBuilder(selectExpression, QueryModelVisitor.QueryCompilationContext)), Expression.Lambda( Expression.Call(queryMethodInfo, queryMethodArguments), _readerParameter))); }