我們所接觸的一個(gè)系統(tǒng)在導(dǎo)出數(shù)據(jù)到Excel的時(shí)候,產(chǎn)生了內(nèi)存溢出的錯(cuò)誤。原因在于數(shù)據(jù)過(guò)大,它導(dǎo)出是將所有數(shù)據(jù)存放在一個(gè)DataSet的一個(gè)表中,再將這個(gè)數(shù)據(jù)集放入session,在導(dǎo)出功能所在的頁(yè)面再讀取該session的值,并綁定在一個(gè)DataGrid,再進(jìn)行相關(guān)導(dǎo)出處理。因?yàn)橄到y(tǒng)不是我們開(kāi)發(fā)的,我們就打算在數(shù)據(jù)存入session的時(shí)候,將數(shù)據(jù)表分解成多個(gè)表存入DataSet,這樣在綁定DataGrid并處理的時(shí)候,能夠一個(gè)個(gè)table的處理。測(cè)試后證明,方法是成功了。下面就把代碼一貼,有類(lèi)似需求的可以大概看看,希望能有所幫助。
C# 代碼:
/// <summary>
/// 分解數(shù)據(jù)表
/// </summary>
/// <param name="originalTab">需要分解的表</param>
/// <param name="rowsNum">每個(gè)表包含的數(shù)據(jù)量</param>
/// <returns></returns>
public DataSet SplitDataTable(DataTable originalTab, int rowsNum)
{
//獲取所需創(chuàng)建的表數(shù)量
int tableNum = originalTab.Rows.Count / rowsNum;
//獲取數(shù)據(jù)余數(shù)
int remainder = originalTab.Rows.Count % rowsNum;
DataSet ds = new DataSet();
//如果只需要?jiǎng)?chuàng)建1個(gè)表,直接將原始表存入DataSet
if (tableNum == 0)
{
ds.Tables.Add(originalTab);
}
else
{
DataTable[] tableSlice = new DataTable[tableNum];
//Save orginal columns into new table.
for (int c = 0; c<tableNum; c++)
{
tableSlice[c] = new DataTable();
foreach(DataColumn dc in originalTab.Columns)
{
tableSlice[c].Columns.Add(dc.ColumnName,dc.DataType);
}
}
//Import Rows
for (int i = 0; i < tableNum; i ++)
{
// if the current table is not the last one
if (i != tableNum -1)
{
for(int j = i*rowsNum ; j < ((i+1)*rowsNum); j++)
{
tableSlice[i].ImportRow(originalTab.Rows[j]);
}
}
else
{
for(int k = i*rowsNum ; k < ((i+1)*rowsNum+remainder); k++)
{
tableSlice[i].ImportRow(originalTab.Rows[k]);
}
}
}
//add all tables into a dataset
foreach(DataTable dt in tableSlice)
{
ds.Tables.Add(dt);
}
}
return ds;
}
VB.NET 代碼:
'===============================================================================
' Author: Ray Chang
' Date: 2007/04/11
' Description: This function splits a givin datatabe into several tables and
' create a new dataset to hold these tables.
'================================================================================
Public Function SplitDataTable(ByVal originalTab As DataTable, ByVal rowsNum As Integer) As DataSet
Dim tableNum As Integer = originalTab.Rows.Count \ rowsNum
Dim remainder As Integer = originalTab.Rows.Count Mod rowsNum
Dim ds As DataSet = New DataSet
'if one table is big enough to store, use one table
If tableNum = 0 Then
ds.Tables.Add(originalTab)
Else
Dim tableSlice(tableNum - 1) As DataTable
'Save orginal columns into new table
Dim c As Integer
For c = 0 To (tableNum - 1)
tableSlice(c) = New DataTable
For Each dc As DataColumn In originalTab.Columns
tableSlice(c).Columns.Add(dc.ColumnName, dc.DataType)
Next
Next
'Import Rows
Dim i As Integer
For i = 0 To (tableNum - 1)
'if the current table is not the last table
If i <> tableNum - 1 Then
Dim j As Integer
For j = i * rowsNum To (((i + 1) * rowsNum) - 1)
tableSlice(i).ImportRow(originalTab.Rows(j))
Next
Else
Dim k As Integer
For k = i * rowsNum To (((i + 1) * rowsNum + remainder) - 1)
tableSlice(i).ImportRow(originalTab.Rows(k))
Next
End If
Next
'Add all tables into a dataset
For Each dt As DataTable In tableSlice
ds.Tables.Add(dt)
Next
End If
'return dataset
SplitDataTable = ds
End Function
先用C#寫(xiě)的,可是系統(tǒng)用的卻是VB.NET,只能又轉(zhuǎn)成了VB.NET. 整個(gè)方法返回一個(gè)包含了分解后的table的DataSet, 所傳入的參數(shù)主要2個(gè):一是所需要分解的表,還有一個(gè)是每一個(gè)表所包含的數(shù)據(jù)量,而最后一個(gè)表將會(huì)包含設(shè)定的數(shù)據(jù)量加上余數(shù)。至于轉(zhuǎn)換后如何操作,我就不羅嗦了。
這個(gè)方法應(yīng)用的地方不多,除非特別案例,如果那個(gè)系統(tǒng)從開(kāi)頭設(shè)計(jì)好,估計(jì)后期也不用做這種改動(dòng)??傊N出來(lái),能用到大家就用吧。
- Ray Chang 2007年4月11日
轉(zhuǎn)自:http://www.cnblogs.com/Rayinuk/archive/2008/11/04/709336.html
作者:LiFuyun
出處:http://lifuyun.cnblogs.com
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。