Рейтинг:
2
1DSparrows
@javed я уже прошел по этой ссылке, но еще не исправил свой код на нужной.
Jαved
в чем проблема с решениями, приведенными в ссылке?
1DSparrows
Дим таблицы в виде списка(объект DataTable) = новый список(из объекта DataTable)()
Dim batchSize как целое число
Dim c как целое число = 0
Dim j как целое число = 1
Dim rowCount As Integer = 0
Dim tempDt As DataTable = dt.Clone()
tempDt.Имятаблицы = "scm_move_order" &амп; Дж.Метод toString()
tempDt.Понятно()
Для каждой из строк datarow в ДТ.Строк
количество строк += 1
Дим невров в качестве объекта datarow = tempDt.Невров()
невров.ItemArray = строка.ItemArray
tempDt.Строк.Добавить(невров)
c += 1
Если c = batchSize или rowCount = dt.Rows.Тогда Считай
таблицы.Добавить(tempDt)
j += 1
tempDt = dt.Clone()
tempDt.Имятаблицы = "scm_move_order" &амп; Дж.Метод toString()
tempDt.Понятно()
c = 0
Конец, Если
Следующий
1DSparrows
Я следовал этому коду, но все равно получил ошибку out of memory
Jαved
вы перебираете все строки в главной таблице "dt" не обязательно, и проверка размера пакета находится в середине цикла, это должна быть первая проверка в цикле.
Хотя этот код займет много времени и не оптимизирован.
Maciej Los
Взгляните на верхний правый угол решения. Она называется: система голосования.
Рейтинг:
2
Maciej Los
Похоже, ваша логика неверна... Взгляните на свой код, особенно на подчеркнутые части:
dtArr() = dt.Select("key_id <= 1 And key_id >= 30000").Clone()
dtArr() = dt.Select("key_id <= 31000 And key_id >= 60000").Clone()
dtArr() = dt.Select("key_id <= 61000 And key_id >= 90000").Clone()
dtArr() = dt.Select("key_id <= 91000 And key_id >= 120000").Clone()
dtArr() = dt.Select("key_id <= 121000 And key_id >= 150000").Clone()
Вы смешали
less than
и
greater than
операторы! Другая проблема заключается в том, что вы теряете 1000 записей (31000-3000=1000) между каждой из них.
select
!
Если вы хотите разделить данные на части с 30000 записями, вы можете использовать Linq. Взгляните на пример...
Способ № 1 - копирование данных с помощью key_id
:
//source table
DataTable src = new DataTable();
src.Columns.Add(new DataColumn("key_id", typeof(int)));
//add example data
src = Enumerable.Range(1,100).Select(x=>src.LoadDataRow(new object[]{x}, false)).CopyToDataTable();
int increasement = 30;
int curVal = 1;
//temporary object type of datarow
DataRow[] result = null;
//destination dataset, here we'll store smaller datatables
DataSet ds = new DataSet();
do
{
result = src.AsEnumerable()
.Where(x=>x.Field<int>("key_id")>=curVal && x.Field<int>("key_id")<curVal+increasement)
.ToArray();
if(result.Length>0)
{
DataTable tmp = src.Clone();
tmp = result.CopyToDataTable();
ds.Tables.Add(tmp);
}
curVal+=increasement;
} while(result.Length>0);
Dim src As DataTable = New DataTable()
src.Columns.Add(New DataColumn("key_id", Type.GetType("System.Int32")))
'add example data
src = Enumerable.Range(1,100).Select(Function(x) src.LoadDataRow(New Object(){x}, False)).CopyToDataTable()
Dim increasement As Integer = 30
Dim curVal As Integer = 1
Dim result As DataRow()
Dim ds As DataSet = New DataSet()
Do
result = src.AsEnumerable() _
.Where(Function(x) x.Field(Of Integer)("key_id")>=curVal And x.Field(Of Integer)("key_id")<curVal+increasement) _
.ToArray()
If result.Length>0 Then
Dim tmp As DataTable = src.Clone()
tmp = result.CopyToDataTable()
ds.Tables.Add(tmp)
End If
curVal+=increasement
Loop While(result.Length>0)
Способ № 2 - копирование одного и того же количества строк:
int increasement = 30;
int curVal = 0; //start with 0!
DataRow[] result = null;
DataSet ds = new DataSet();
do
{
result = src.AsEnumerable()
.Skip(curVal) //
.Take(increasement)
.ToArray();
if(result.Length>0)
{
DataTable tmp = src.Clone();
tmp = result.CopyToDataTable();
ds.Tables.Add(tmp);
}
curVal+=increasement;
} while(result.Length>0);
Dim increasement As Integer = 30
Dim curVal As Integer = 0
Dim result As DataRow()= Nothing
Dim ds As DataSet = New DataSet()
Do
result = src.AsEnumerable() _
.Skip(curVal) _
.Take(increasement) _
.ToArray()
If result.Length>0 Then
Dim tmp As DataTable = src.Clone()
tmp = result.CopyToDataTable()
ds.Tables.Add(tmp)
End If
curVal+=increasement
Loop While(result.Length>0)
[РЕДАКТИРОВАТЬ]
Non-Linq решение - метод #1:'needed:
'Imports System.Data
'Imports System.Text
Dim src As DataTable = New DataTable()
src.Columns.Add(New DataColumn("key_id", Type.GetType("System.Int32")))
'add example data
For i As Integer = 0 To 100
src.Rows.Add(New Object() {i})
Next
Dim increasement As Integer = 30
Dim curVal As Integer = 1
Dim result As DataRow()
Dim ds As DataSet = New DataSet()
Do
result = src.Select(String.Format("key_id >={0} And key_id<{1}", curVal, curVal + increasement)).Clone()
If result.Length > 0 Then
Dim tmp As DataTable = src.Clone()
Dim sb As StringBuilder = New StringBuilder()
For Each dr As DataRow In result
tmp.Rows.Add(New Object() {dr("key_id")})
sb.Append(String.Format("{0};", dr("key_id")))
Next
ds.Tables.Add(tmp)
Console.WriteLine("{0}", sb.ToString())
sb = Nothing
End If
curVal += increasement
Loop While (result.Length > 0)
Console.ReadKey()
Результат (4 таблицы):
1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;
31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;57;58;59;60;
61;62;63;64;65;66;67;68;69;70;71;72;73;74;75;76;77;78;79;80;81;82;83;84;85;86;87;88;89;90;
91;92;93;94;95;96;97;98;99;100;
[КОНЕЦ РЕДАКТИРОВАНИЯ]
Удачи вам!
1DSparrows
Я использовал ваш код выше, но методом asenumerable' не является членом 'системы.Данных.Объект DataTable. Я добавляю ссылку, но все равно получаю ошибку. Оба метода не работают. Я использую Visual Studio 2005.
Maciej Los
Вы не упомянули о VS 2005. Да, для VS2005 это не сработает. Я постараюсь найти способ обойтись без Linq.
1DSparrows
Прости, что не упомянул об этом. Я работаю в VS2005.
Maciej Los
Готово! Проверьте мой ответ.
1DSparrows
всегда ли увеличение как целое число = 30, или я могу изменить его на основе диапазона, который мне нужен, чтобы таблица могла иметь? значит, если я поставлю 30000, то в таблице будет каждый 30000?
Maciej Los
Вы можете изменить его в соответствии с вашими потребностями. Я использовал 30, потому что исходная таблица, которую я создал в приведенном выше коде, была заполнена 100 записями. Вы должны обратиться к своему "реальному" DataTable.
1DSparrows
Привет, я все еще получаю ошибку out of memory, когда загружаю 130 000 записей.
Maciej Los
Таким образом, вы должны отладить свой код, чтобы выяснить, что вызывает такую ошибку.
1DSparrows
Код был правильным, но проблема в том, что цикл просто продолжался, и ничего не происходило. Я даже не успел успешно загрузить эти данные в свою базу данных. Таким образом, console.readkey() предназначен для консольного приложения? Я делаю веб-приложение в ASP.NET приложение (например, работающее в IIS).
Я попытался загрузить 50 записей, чтобы проверить, затем я поставил 10 на увеличение, но тогда было загружено только 39 записей.
1DSparrows
Вот как я использовал ваш код:
Если (ДТ.Строк.Граф > 100000) Затем
Дим Scr как объект DataTable = новый объект DataTable()
scr.колонки.Add(New DataColumn("key_id", Type.Метод Gettype (Системы".Типа int32")))
Для _c как целого числа = 0 до dt.строк.Рассчитывать
scr.Rows.Add(New Object() {_c})
Следующий
Дим организма как целого = 30000
Dim curVal As Integer = 1
Тусклый результат как DataRow()
Dim ds As DataSet = новый набор данных()
Делать
результат = ОПЗ.Выберите(Строка.Формат("key_id >={0} и key_id<{1}", curVal, curVal + increasement)).Клон()
Если результат.Длина > 0 затем
Dim tmp As DataTable = scr.Клон()
Dim sb As StringBuilder = новый StringBuilder()
Для каждого dr As DataRow в результате
tmp.Rows.Add(New Object() {dr("key_id")})
sb.Append(строка.Формат("{0};", dr("key_id")))
Следующий
ДС.столы.Добавить(tmp)
Приставка.WriteLine("{0}", sb.ToString())
sb = ничего
Конец, Если
кривизна += увеличение
Цикл While (результат.Длина > 0)
Конец, Если
ДТ.Метода writexml(писатель, ложные)