/// <summary> /// Reads from the reader until there are no more results to read /// </summary> /// <param name="cancellationToken">Cancellation token for cancelling the query</param> public async Task ReadResultToEnd(CancellationToken cancellationToken) { // Mark that result has been read hasBeenRead = true; // Open a writer for the file using (IFileStreamWriter fileWriter = fileStreamFactory.GetWriter(outputFileName, MaxCharsToStore, MaxXmlCharsToStore)) { // If we can initialize the columns using the column schema, use that if (!DataReader.DbDataReader.CanGetColumnSchema()) { throw new InvalidOperationException(SR.QueryServiceResultSetNoColumnSchema); } Columns = DataReader.Columns; long currentFileOffset = 0; while (await DataReader.ReadAsync(cancellationToken)) { RowCount++; FileOffsets.Add(currentFileOffset); currentFileOffset += fileWriter.WriteRow(DataReader); } } // Check if resultset is 'for xml/json'. If it is, set isJson/isXml value in column metadata SingleColumnXmlJsonResultSet(); }
/// <summary> /// Generates a subset of the rows from the result set /// </summary> /// <param name="startRow">The starting row of the results</param> /// <param name="rowCount">How many rows to retrieve</param> /// <returns>A subset of results</returns> public Task <ResultSetSubset> GetSubset(int startRow, int rowCount) { // Sanity check to make sure that the results have been read beforehand if (!hasBeenRead) { throw new InvalidOperationException(SR.QueryServiceResultSetNotRead); } // Sanity check to make sure that the row and the row count are within bounds if (startRow < 0 || startRow >= RowCount) { throw new ArgumentOutOfRangeException(nameof(startRow), SR.QueryServiceResultSetStartRowOutOfRange); } if (rowCount <= 0) { throw new ArgumentOutOfRangeException(nameof(rowCount), SR.QueryServiceResultSetRowCountOutOfRange); } return(Task.Factory.StartNew(() => { string[][] rows; using (IFileStreamReader fileStreamReader = fileStreamFactory.GetReader(outputFileName)) { // If result set is 'for xml' or 'for json', // Concatenate all the rows together into one row if (isSingleColumnXmlJsonResultSet) { // Iterate over all the rows and process them into a list of string builders IEnumerable <string> rowValues = FileOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, Columns)[0].DisplayValue); rows = new[] { new[] { string.Join(string.Empty, rowValues) } }; } else { // Figure out which rows we need to read back IEnumerable <long> rowOffsets = FileOffsets.Skip(startRow).Take(rowCount); // Iterate over the rows we need and process them into output rows = rowOffsets.Select(rowOffset => fileStreamReader.ReadRow(rowOffset, Columns).Select(cell => cell.DisplayValue).ToArray()) .ToArray(); } } // Retrieve the subset of the results as per the request return new ResultSetSubset { Rows = rows, RowCount = rows.Length }; })); }