protected override Expression VisitEntityQueryable(Type elementType) { var relationalQueryCompilationContext = ((RelationalQueryCompilationContext)QueryModelVisitor.QueryCompilationContext); var queryMethodInfo = CreateValueReaderMethodInfo; var entityType = QueryModelVisitor.QueryCompilationContext.Model.GetEntityType(elementType); var selectExpression = new SelectExpression(); var tableName = entityType.TableName(); selectExpression .AddTable( new TableExpression( tableName, entityType.Schema(), _querySource.ItemName.StartsWith("<generated>_") ? tableName.First().ToString().ToLower() : _querySource.ItemName, _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)); queryMethodArguments.Add(Expression.Constant(entityType)); } return(Expression.Call( relationalQueryCompilationContext.QueryMethodProvider.QueryMethod .MakeGenericMethod(queryMethodInfo.ReturnType), QueryContextParameter, Expression.Constant(new CommandBuilder(selectExpression, relationalQueryCompilationContext)), Expression.Lambda( Expression.Call(queryMethodInfo, queryMethodArguments), _readerParameter))); }
protected override Expression VisitEntityQueryable(Type elementType) { Check.NotNull(elementType, nameof(elementType)); var queryMethodInfo = CreateValueBufferMethodInfo; var relationalQueryCompilationContext = QueryModelVisitor.QueryCompilationContext; var entityType = relationalQueryCompilationContext.Model.GetEntityType(elementType); var selectExpression = new SelectExpression(); var name = relationalQueryCompilationContext.RelationalExtensions.For(entityType).TableName; var tableAlias = _querySource.HasGeneratedItemName() ? name[0].ToString().ToLower() : _querySource.ItemName; var fromSqlAnnotation = relationalQueryCompilationContext .GetCustomQueryAnnotations(RelationalQueryableExtensions.FromSqlMethodInfo) .LastOrDefault(a => a.QuerySource == _querySource); var composable = true; var sqlString = ""; object[] sqlParameters = null; if (fromSqlAnnotation == null) { selectExpression.AddTable( new TableExpression( name, relationalQueryCompilationContext.RelationalExtensions.For(entityType).Schema, tableAlias, _querySource)); } else { sqlString = (string)fromSqlAnnotation.Arguments[1]; sqlParameters = (object[])fromSqlAnnotation.Arguments[2]; selectExpression.AddTable( new RawSqlDerivedTableExpression( sqlString, sqlParameters, tableAlias, _querySource)); var sqlStart = sqlString.SkipWhile(char.IsWhiteSpace).Take(7).ToArray(); if (sqlStart.Length != 7 || !char.IsWhiteSpace(sqlStart.Last()) || !new string(sqlStart).StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)) { if (relationalQueryCompilationContext.QueryAnnotations .OfType <IncludeQueryAnnotation>().Any()) { throw new InvalidOperationException(Strings.StoredProcedureIncludeNotSupported); } QueryModelVisitor.RequiresClientEval = true; composable = false; } if (!fromSqlAnnotation.QueryModel.BodyClauses.Any() && !fromSqlAnnotation.QueryModel.ResultOperators.Any()) { composable = false; } } QueryModelVisitor.AddQuery(_querySource, selectExpression); var queryMethodArguments = new List <Expression> { Expression.Constant(_querySource), EntityQueryModelVisitor.QueryContextParameter, EntityQueryModelVisitor.QueryResultScopeParameter, _valueBufferParameter, Expression.Constant(0) }; if (QueryModelVisitor.QueryCompilationContext .QuerySourceRequiresMaterialization(_querySource) || QueryModelVisitor.RequiresClientEval) { var materializer = new MaterializerFactory( relationalQueryCompilationContext .EntityMaterializerSource) .CreateMaterializer( entityType, selectExpression, (p, se) => se.AddToProjection( relationalQueryCompilationContext.RelationalExtensions.For(p).ColumnName, p, _querySource), QueryModelVisitor.QueryCompilationContext.RelationalExtensions, _querySource); queryMethodInfo = CreateEntityMethodInfo.MakeGenericMethod(elementType); var keyFactory = relationalQueryCompilationContext.EntityKeyFactorySource .GetKeyFactory(entityType.GetPrimaryKey()); queryMethodArguments.AddRange( new[] { Expression.Constant(entityType), Expression.Constant(QueryModelVisitor.QuerySourceRequiresTracking(_querySource)), Expression.Constant(keyFactory), Expression.Constant(entityType.GetPrimaryKey().Properties), materializer }); } Func <ISqlQueryGenerator> sqlQueryGeneratorFactory; if (composable) { sqlQueryGeneratorFactory = () => relationalQueryCompilationContext.CreateSqlQueryGenerator(selectExpression); } else { sqlQueryGeneratorFactory = () => new RawSqlQueryGenerator(selectExpression, sqlString, sqlParameters, relationalQueryCompilationContext.TypeMapper); } return(Expression.Call( relationalQueryCompilationContext.QueryMethodProvider.ShapedQueryMethod .MakeGenericMethod(queryMethodInfo.ReturnType), EntityQueryModelVisitor.QueryContextParameter, Expression.Constant( new CommandBuilder( sqlQueryGeneratorFactory, relationalQueryCompilationContext.ValueBufferFactoryFactory)), Expression.Lambda( Expression.Call(queryMethodInfo, queryMethodArguments), _valueBufferParameter))); }