1123レコードのデータテーブルがあります。このテーブルを5つの固定サイズの個別のデータテーブルに分割したいと思います。各テーブルのサイズ制限は225です。
したがって、結果のデータテーブルのサイズは次のようになります。
DT1 : 225 rows
DT2 : 225 rows
DT3 : 225 rows
DT4 : 225 rows
DT5 : 223 rows (remaining rows)
LINQ here を使用して、列の値に基づいてデータテーブルを分割する方法を見つけることができました。
データテーブルを複数のテーブルに分割する方法も見つけました here 。これを行うより良い方法があるかどうか知りたいと思った。リンクからの投稿コード:
private static List<DataTable> SplitTable(DataTable originalTable, int batchSize)
{
List<DataTable> tables = new List<DataTable>();
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<IEnumerable<T>> ToChunks<T>(this IEnumerable<T> 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<DataTable> SplitTable(DataTable originalTable, int batchSize)
{
List<DataTable> tables = new List<DataTable>();
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<T>(IEnumerable<T> 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);