将数据表拆分为多个固定大小的表

我有一个有1123条记录的数据表。 我想将此表拆分为5个固定大小的单独数据表。 每张表的大小限制为225。

因此产生的数据表的大小将是:

DT1 : 225 rows DT2 : 225 rows DT3 : 225 rows DT4 : 225 rows DT5 : 223 rows (remaining rows) 

我能够在这里找到如何使用LINQ基于列值拆分数据表。

我还找到了一种将数据表拆分为多个表的方法。 想知道是否有更好的方法。 从链接发布代码:

 private static List SplitTable(DataTable originalTable, int batchSize) { List tables = new List(); int i = 0; int j = 1; DataTable newDt = originalTable.Clone(); newDt.TableName = "Table_" + j; newDt.Clear(); foreach (DataRow row in originalTable.Rows) { DataRow newRow = newDt.NewRow(); newRow.ItemArray = row.ItemArray; newDt.Rows.Add(newRow); i++; if (i == batchSize) { tables.Add(newDt); j++; newDt = originalTable.Clone(); newDt.TableName = "Table_" + j; newDt.Clear(); i = 0; } } return tables; } 

需要帮助将数据表拆分为固定大小。

我曾经做过这个小扩展方法 :

 public static IEnumerable> ToChunks(this IEnumerable enumerable, int chunkSize) { int itemsReturned = 0; var list = enumerable.ToList(); // Prevent multiple execution of IEnumerable. int count = list.Count; while (itemsReturned < count) { int currentChunkSize = Math.Min(chunkSize, count - itemsReturned); yield return list.GetRange(itemsReturned, currentChunkSize); itemsReturned += currentChunkSize; } } 

将任何IEnumerable切割成指定块大小的块。

有了这个,你可以简单地做:

 var tables = originalTable.AsEnumerable().ToChunks(225) .Select(rows => rows.CopyToDataTable()) 

这可能比直接的foreach表现更好的原因是list.GetRange是从列表中获取一系列行的一种非常有效的方法。 我很想知道你会发现什么。

 private static List SplitTable(DataTable originalTable, int batchSize) { List tables = new List(); int i = 0; int j = 1; DataTable newDt = originalTable.Clone(); newDt.TableName = "Table_" + j; newDt.Clear(); foreach (DataRow row in originalTable.Rows) { DataRow newRow = newDt.NewRow(); newRow.ItemArray = row.ItemArray; newDt.Rows.Add(newRow); i++; if (i == batchSize) { tables.Add(newDt); j++; newDt = originalTable.Clone(); newDt.TableName = "Table_" + j; newDt.Clear(); i = 0; } } if (newDt.Rows.Count > 0) { tables.Add(newDt); j++; newDt = originalTable.Clone(); newDt.TableName = "Table_" + j; newDt.Clear(); } return tables; } foreach (var dt1 in SplitTable(table1, 2)) { DataTable dt = dt1; } 

为懒人做另一种方式:)

 private static DataTable GetDataTable(IEnumerable data, int skip, int take) { var properties = TypeDescriptor.GetProperties(typeof(T)); var dataTable = new DataTable(); foreach (PropertyDescriptor prop in properties) dataTable .Columns .Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (var item in data.Skip(skip).Take(take)) { var row = dataTable.NewRow(); foreach (PropertyDescriptor prop in properties) row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; dataTable.Rows.Add(row); } return dataTable; } 

客户端会这样称呼它:

  `var nthDataTable = GetDataTable(model, skip: n, take: m);` 

这里给出的解决方案对我来说不起作用,如果最后一组记录小于所需的块数据表大小那么它将简单地忽略那些记录并导致丢失它们…如果有5个记录和块表大小则为ex是2然后它将只创建2个数据表忽略最后一个记录。

以下是在所有情况下都适用于我的更正代码。

使用VB.NET的用户可能会也可能无法多次使用LINQ,因此如果您需要相同的vb.net代码,请查看此处将大型数据表拆分为c#和vb.net中的块

  private static List SplitTable(DataTable mainTable, int batchSize) { List tables = new List(); int i = 0; int j = 1; int rowCount = 0; DataTable tempDt = mainTable.Clone(); tempDt.TableName = "ChunkDataTable" + j.ToString(); tempDt.Clear(); foreach (DataRow row in mainTable.Rows) { rowCount += 1; DataRow newRow = tempDt.NewRow(); newRow.ItemArray = row.ItemArray; tempDt.Rows.Add(newRow); i += 1; if (i == batchSize | rowCount == mainTable.Rows.Count) { tables.Add(tempDt); j += 1; tempDt = mainTable.Clone(); tempDt.TableName = "ChunkDataTable" + j.ToString(); tempDt.Clear(); i = 0; } } return tables; }