/// <summary> /// Create the data reader. /// </summary> /// <param name="layer">Data access layer that will give us the TextReader we need.</param> /// <param name="mapping">ClassMapping for the type we're returning.</param> /// <param name="criteria">Since there is no way to filter before we read the file, /// the reader checks each row read to see if it matches the /// criteria, if not, it is skipped.</param> public CsvDataReader(CsvDaLayer layer, ClassMapping mapping, DaoCriteria criteria) : base(layer, mapping, criteria, GetConfig(layer, mapping)) { _reader = ((CsvDataReaderConfig) _config).Reader; try { PreProcessSorts(); } catch (Exception e) { // Close the reader on error, since if the constructor throws // it isn't very reasonable to expect anyone else to call Close. if (_reader != null) { layer.DoneWithReader(_reader); } throw new LoggingException("Unable to read from CSV file and process sorts.", e); } }
private static DataReaderConfig GetConfig(CsvDaLayer layer, ClassMapping mapping) { CsvDataReaderConfig retVal = new CsvDataReaderConfig(); try { retVal.Reader = layer.GetReader(mapping); if (CsvDaLayer.UseNamedColumns(mapping)) { // If the CSV has row headers, read the header row. IList colNameRow = ReadRawCsvRow(retVal.Reader); for (int x = 0; x < colNameRow.Count; x++) { retVal.IndexesByName[colNameRow[x].ToString()] = x; } } else { // No row headers, so we must be mapped to column numbers. // In that case, just map the column number strings to the ints. foreach (string colStr in mapping.AllDataColsInOrder) { // Remember the mapping column numbers are 1-based but // the internal column numbers are 0-based. retVal.IndexesByName[colStr] = int.Parse(colStr) - 1; } } return retVal; } catch (Exception e) { // Problem setting up, close the reader. if (retVal.Reader != null) { layer.DoneWithReader(retVal.Reader); } throw new LoggingException("Unable to begin reading from CSV file.", e); } }