private object[] SetupSchemaWithoutKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, bool gettingData, DataColumn parentChapterColumn, object chapterValue)
{
int[] columnIndexMap = null;
bool[] chapterIndexMap = null;
int mappingCount = 0;
int count = _dataReader.FieldCount;
object[] dataValues = null;
List<object> addedItems = null;
try
{
DataColumnCollection columnCollection = _dataTable.Columns;
columnCollection.EnsureAdditionalCapacity(count + (chapterValue != null ? 1 : 0));
// We can always just create column if there are no existing column or column mappings, and the mapping action is passthrough
bool alwaysCreateColumns = ((_dataTable.Columns.Count == 0) && ((_tableMapping.ColumnMappings == null) || (_tableMapping.ColumnMappings.Count == 0)) && (mappingAction == MissingMappingAction.Passthrough));
for (int i = 0; i < count; ++i)
{
bool ischapter = false;
Type fieldType = _dataReader.GetFieldType(i);
if (null == fieldType)
{
throw ADP.MissingDataReaderFieldType(i);
}
// if IDataReader, hierarchy exists and we will use an Int32,AutoIncrementColumn in this table
if (typeof(IDataReader).IsAssignableFrom(fieldType))
{
if (null == chapterIndexMap)
{
chapterIndexMap = new bool[count];
}
chapterIndexMap[i] = ischapter = true;
fieldType = typeof(int);
}
else if (typeof(System.Data.SqlTypes.SqlXml).IsAssignableFrom(fieldType))
{
if (null == _xmlMap)
{ // map to DataColumn with DataType=typeof(SqlXml)
_xmlMap = new int[count];
}
_xmlMap[i] = SqlXml; // track its xml data
}
else if (typeof(System.Xml.XmlReader).IsAssignableFrom(fieldType))
{
fieldType = typeof(string); // map to DataColumn with DataType=typeof(string)
if (null == _xmlMap)
{
_xmlMap = new int[count];
}
_xmlMap[i] = XmlDocument; // track its xml data
}
DataColumn dataColumn;
if (alwaysCreateColumns)
{
dataColumn = DataColumnMapping.CreateDataColumnBySchemaAction(_fieldNames[i], _fieldNames[i], _dataTable, fieldType, schemaAction);
}
else
{
dataColumn = _tableMapping.GetDataColumn(_fieldNames[i], fieldType, _dataTable, mappingAction, schemaAction);
}
if (null == dataColumn)
{
if (null == columnIndexMap)
{
columnIndexMap = CreateIndexMap(count, i);
}
columnIndexMap[i] = -1;
continue; // null means ignore (mapped to nothing)
}
else if ((null != _xmlMap) && (0 != _xmlMap[i]))
{
if (typeof(System.Data.SqlTypes.SqlXml) == dataColumn.DataType)
{
_xmlMap[i] = SqlXml;
}
else if (typeof(System.Xml.XmlDocument) == dataColumn.DataType)
{
_xmlMap[i] = XmlDocument;
}
else
{
_xmlMap[i] = 0; // datacolumn is not a specific Xml dataType, i.e. string
int total = 0;
for (int x = 0; x < _xmlMap.Length; ++x)
{
total += _xmlMap[x];
}
if (0 == total)
{ // not mapping to a specific Xml datatype, get rid of the map
_xmlMap = null;
}
}
}
if (null == dataColumn.Table)
{
if (ischapter)
{
dataColumn.AllowDBNull = false;
dataColumn.AutoIncrement = true;
dataColumn.ReadOnly = true;
}
AddItemToAllowRollback(ref addedItems, dataColumn);
columnCollection.Add(dataColumn);
}
else if (ischapter && !dataColumn.AutoIncrement)
{
throw ADP.FillChapterAutoIncrement();
}
if (null != columnIndexMap)
{
columnIndexMap[i] = dataColumn.Ordinal;
}
else if (i != dataColumn.Ordinal)
{
columnIndexMap = CreateIndexMap(count, i);
columnIndexMap[i] = dataColumn.Ordinal;
}
// else i == dataColumn.Ordinal and columnIndexMap can be optimized out
mappingCount++;
}
bool addDataRelation = false;
DataColumn chapterColumn = null;
if (null != chapterValue)
{ // add the extra column in the child table
Type fieldType = chapterValue.GetType();
chapterColumn = _tableMapping.GetDataColumn(_tableMapping.SourceTable, fieldType, _dataTable, mappingAction, schemaAction);
if (null != chapterColumn)
{
if (null == chapterColumn.Table)
{
AddItemToAllowRollback(ref addedItems, chapterColumn);
columnCollection.Add(chapterColumn);
addDataRelation = (null != parentChapterColumn);
}
mappingCount++;
}
}
if (0 < mappingCount)
{
if ((null != _dataSet) && (null == _dataTable.DataSet))
{
// Allowed to throw exception if DataTable is from wrong DataSet
AddItemToAllowRollback(ref addedItems, _dataTable);
_dataSet.Tables.Add(_dataTable);
}
if (gettingData)
{
if (null == columnCollection)
{
columnCollection = _dataTable.Columns;
}
_indexMap = columnIndexMap;
_chapterMap = chapterIndexMap;
dataValues = SetupMapping(count, columnCollection, chapterColumn, chapterValue);
}
else
{
// debug only, but for retail debug ability
_mappedMode = -1;
}
}
else
{
_dataTable = null;
}
if (addDataRelation)
{
AddRelation(parentChapterColumn, chapterColumn);
}
}
catch (Exception e) when (ADP.IsCatchableOrSecurityExceptionType(e))
{
RollbackAddedItems(addedItems);
throw;
}
return dataValues;
}