NSwag客户端返回的ICollection转DataTable实现Oracle表批量插入
Input array is longer than the number of columns in this table异常的根本原因是自定义的ToDataTable方法没有提前为DataTable创建与类属性对应的列:实例化DataTable后默认列数为0,插入数据时传入的属性值数组长度等于类属性数量,远大于当前列数,自然抛出参数异常,和可空类型没有直接关系。
修复后的自定义转换代码
public class ListToDataTable { public DataTable ToDataTable<T>(List<T> items) { DataTable dataTable = new(typeof(T).Name); PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); // 提前创建与类属性对应的列,兼容可空值类型 foreach (PropertyInfo prop in props) { Type columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; dataTable.Columns.Add(prop.Name, columnType); } foreach(T item in items) { var values = new object[props.Length]; for(int i = 0; i < props.Length; i++) { // 属性值为null时替换为DBNull.Value,适配DataTable的取值规则 values[i] = props[i].GetValue(item) ?? DBNull.Value; } dataTable.Rows.Add(values); } return dataTable; } }
转换完成的DataTable可以直接传入OracleBulkCopy进行批量插入,无需引入EF Core等重型组件。
简化方案
如果不想自行维护转换逻辑,可以直接使用MoreLinq提供的ToDataTable扩展方法,一行代码即可完成转换,无需自行处理列创建、可空类型兼容等逻辑:
ICollection<ActionPlans> actionPlans = client.ActionPlansAsync(apiKey).GetAwaiter().GetResult(); _logger.LogInformation($"{actionPlans.Count} APs returned"); DataTable actionPlansDt = actionPlans.ToDataTable();
内容的提问来源于stack exchange,提问作者Rob M
相关产品推荐
相关产品推荐

