示例#1
0
 public LoadRowsSettings(LoadRowsSettings other)
     : this()
 {
     if (other == null)
     {
         return;
     }
     this.RowAddErrorHandler     = other.RowAddErrorHandler;
     this.RowNumberColumnName    = other.RowNumberColumnName;
     this.DuplicateColumnRenamer = other.DuplicateColumnRenamer;
     this.ColumnMapper           = other.ColumnMapper;
     this.TypeConverter          = other.TypeConverter;
 }
示例#2
0
        public static void LoadRows(this DataTable dt, IEnumerable <IList <object> > rows, LoadRowsSettings settings = null)
        {
            RequiresZeroRows(dt, nameof(dt));
            Requires.NonNull(rows, nameof(rows));
            settings = settings ?? new LoadRowsSettings();

            var e = rows.GetEnumerator();

            if (!e.MoveNext())
            {
                return;
            }

            bool       createColumns   = dt.Columns.Count == 0;
            DataColumn rowNumberColumn = null;

            if (settings.RowNumberColumnName != null)
            {
                rowNumberColumn = dt.Columns[settings.RowNumberColumnName];
                if (rowNumberColumn == null)
                {
                    rowNumberColumn = new DataColumn(settings.RowNumberColumnName, typeof(int))
                    {
                        AllowDBNull = false
                    };
                    dt.Columns.Add(rowNumberColumn);
                }
                else
                {
                    if (!(rowNumberColumn.DataType == typeof(int) || rowNumberColumn.DataType == typeof(long)))
                    {
                        throw new InvalidOperationException(string.Format("Existing table has a rowNumberColumn of an incompatible data type"));
                    }
                }
            }

            var headerRow              = e.Current;
            var columnMapper           = settings.ColumnMapper ?? DataTableHelpers.OneToOneColumnNameMapper;
            var duplicateColumnRenamer = settings.DuplicateColumnRenamer ?? DataTableHelpers.OnDuplicateColumnNameThrow;
            var columnMap              = new DataColumn[headerRow.Count];

            for (int z = 0; z < headerRow.Count(); ++z)
            {
                var colName = StringHelpers.TrimOrNull(Stuff.ObjectToString(headerRow[z]));
                if (colName == null)
                {
                    continue;
                }
                colName = columnMapper(colName);
                if (colName == null)
                {
                    continue;
                }
                var c = dt.Columns[colName];
                if (createColumns)
                {
                    if (c == null)
                    {
                        c = new DataColumn(colName);
                        dt.Columns.Add(c);
                    }
                    else
                    {
                        colName = duplicateColumnRenamer(dt, colName);
                        c       = new DataColumn(colName);
                        dt.Columns.Add(c);
                    }
                }
                else if (c == null)
                {
                    Trace.WriteLine(string.Format("Will ignore source column #{0} with name=[{1}]", z, colName));
                }
                columnMap[z] = c;
            }

            int rowNum        = -1;
            var onRowAddError = settings.RowAddErrorHandler ?? RowAddErrorRethrow;

            while (e.MoveNext())
            {
                ++rowNum;
                var row = e.Current;
                if (row.Count == 0)
                {
                    continue;
                }
                var fields = new object[dt.Columns.Count];
                try
                {
                    for (int z = 0; z < columnMap.Length; ++z)
                    {
                        var c = columnMap[z];
                        if (c == null)
                        {
                            continue;
                        }
                        object val = z >= row.Count ? null : row[z];
                        if (val == null)
                        {
                            val = DBNull.Value;
                        }
                        else
                        {
                            var t = val.GetType();
                            if (t != c.DataType)
                            {
                                if (c.AllowDBNull && c.DataType.IsNumber() && null == StringHelpers.TrimOrNull(Stuff.ObjectToString(val)))
                                {
                                    val = DBNull.Value;
                                }
                                else
                                {
                                    try
                                    {
                                        val = settings.TypeConverter(val, c.DataType);
                                    }
                                    catch (Exception tcex)
                                    {
                                        throw new Exception($"Problem with row {rowNum} column {z} converting {val} to type {c.DataType.Name} into store [{dt.TableName}]", tcex);
                                    }
                                }
                            }
                        }
                        fields[c.Ordinal] = val;
                    }
                    if (rowNumberColumn != null)
                    {
                        fields[rowNumberColumn.Ordinal] = rowNum;
                    }
                    if (null == settings.ShouldAddRow || settings.ShouldAddRow(dt, fields))
                    {
                        dt.Rows.Add(fields);
                    }
                }
                catch (Exception ex)
                {
                    onRowAddError(ex, rowNum);
                }
            }
        }
示例#3
0
 public LoadRowsFromSpreadsheetSettings(LoadRowsSettings other)
     : base(other)
 {
 }