// Constructors /// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="handlers">The handlers.</param> /// <param name="request">The request.</param> /// <param name="tableDescriptor">The table descriptor.</param> /// <param name="filterDataSource">The filter data source.</param> /// <param name="origin">The origin.</param> /// <param name="source">The source.</param> public SqlIncludeProvider( HandlerAccessor handlers, QueryRequest request, TemporaryTableDescriptor tableDescriptor, Func <IEnumerable <Tuple> > filterDataSource, IncludeProvider origin, ExecutableProvider source) : base(handlers, request, tableDescriptor, origin, new [] { source }) { this.filterDataSource = filterDataSource; Initialize(); }
protected SqlExpression CreateIncludeViaComplexConditionExpression( IncludeProvider provider, Func <object> valueAccessor, IList <SqlExpression> sourceColumns, out QueryParameterBinding binding) { var filterTupleDescriptor = provider.FilteredColumnsExtractionTransform.Descriptor; var mappings = filterTupleDescriptor.Select(type => Driver.GetTypeMapping(type)); binding = new QueryRowFilterParameterBinding(mappings, valueAccessor); var resultExpression = SqlDml.DynamicFilter(binding); resultExpression.Expressions.AddRange(provider.FilteredColumns.Select(index => sourceColumns[index])); return(resultExpression); }
protected override Provider VisitInclude(IncludeProvider provider) { int sourceLength = provider.Source.Header.Length; mappings[provider.Source] = Merge(mappings[provider].Where(i => i < sourceLength), provider.FilteredColumns); var source = VisitCompilable(provider.Source); mappings[provider] = Merge(mappings[provider], mappings[provider.Source]); if (source == provider.Source) { return(provider); } var filteredColumns = provider.FilteredColumns.Select(el => mappings[provider].IndexOf(el)).ToArray(); return(new IncludeProvider(source, provider.Algorithm, provider.IsInlined, provider.FilterDataSource, provider.ResultColumnName, filteredColumns)); }
protected SqlExpression CreateIncludeViaTemporaryTableExpression( IncludeProvider provider, IList <SqlExpression> sourceColumns, out TemporaryTableDescriptor tableDescriptor) { var filterTupleDescriptor = provider.FilteredColumnsExtractionTransform.Descriptor; var filteredColumns = provider.FilteredColumns.Select(index => sourceColumns[index]).ToList(); tableDescriptor = DomainHandler.TemporaryTableManager .BuildDescriptor(Mapping, Guid.NewGuid().ToString(), filterTupleDescriptor); var filterQuery = tableDescriptor.QueryStatement.ShallowClone(); var tableRef = filterQuery.From; for (int i = 0; i < filterTupleDescriptor.Count; i++) { filterQuery.Where &= filteredColumns[i] == tableRef[i]; } var resultExpression = SqlDml.Exists(filterQuery); return(resultExpression); }
/// <summary> /// Compiles <see cref="IncludeProvider"/>. /// </summary> /// <param name="provider">Include provider.</param> protected abstract TResult VisitInclude(IncludeProvider provider);
/// <inheritdoc/> protected override SqlProvider VisitInclude(IncludeProvider provider) { var source = Compile(provider.Source); var resultQuery = ExtractSqlSelect(provider, source); var sourceColumns = ExtractColumnExpressions(resultQuery); var bindings = source.Request.ParameterBindings; var filterDataSource = provider.FilterDataSource.CachingCompile(); var requestOptions = QueryRequestOptions.Empty; SqlExpression resultExpression; TemporaryTableDescriptor tableDescriptor = null; QueryParameterBinding extraBinding = null; var algorithm = provider.Algorithm; if (!temporaryTablesSupported) { algorithm = IncludeAlgorithm.ComplexCondition; } switch (algorithm) { case IncludeAlgorithm.Auto: var complexConditionExpression = CreateIncludeViaComplexConditionExpression( provider, BuildRowFilterParameterAccessor(filterDataSource, true), sourceColumns, out extraBinding); var temporaryTableExpression = CreateIncludeViaTemporaryTableExpression( provider, sourceColumns, out tableDescriptor); resultExpression = SqlDml.Variant(extraBinding, complexConditionExpression, temporaryTableExpression); anyTemporaryTablesRequired = true; break; case IncludeAlgorithm.ComplexCondition: resultExpression = CreateIncludeViaComplexConditionExpression( provider, BuildRowFilterParameterAccessor(filterDataSource, false), sourceColumns, out extraBinding); if (!anyTemporaryTablesRequired) { requestOptions |= QueryRequestOptions.AllowOptimization; } break; case IncludeAlgorithm.TemporaryTable: resultExpression = CreateIncludeViaTemporaryTableExpression( provider, sourceColumns, out tableDescriptor); anyTemporaryTablesRequired = true; break; default: throw new ArgumentOutOfRangeException("provider.Algorithm"); } resultExpression = GetBooleanColumnExpression(resultExpression); var calculatedColumn = provider.Header.Columns[provider.Header.Length - 1]; AddInlinableColumn(provider, calculatedColumn, resultQuery, resultExpression); if (extraBinding != null) { bindings = bindings.Concat(EnumerableUtils.One(extraBinding)); } var request = CreateQueryRequest(Driver, resultQuery, bindings, provider.Header.TupleDescriptor, requestOptions); return(new SqlIncludeProvider(Handlers, request, tableDescriptor, filterDataSource, provider, source)); }