Member 12478311 Ответов: 3

Как хранить определенные строки из одного набора данных в другой.


У меня есть набор данных дс который имеет 200 строк.

Я создал 2 новых набора данных источник данных DS1, DS2 у.

Теперь при нажатии кнопки в приложении Windows forms,

Мне нужно получить первые 100 строк из набора данных дс и хранить в новом наборе данных бс1,
затем следующие 100 строк в наборе данных DS2 у.

Что я уже пробовал:

Может ли кто-нибудь, пожалуйста, дать мне какие-либо предложения о том, как это сделать..

Спасибо..

njammy

Можете ли вы использовать Linq в своем решении? дайте мне знать. в противном случае я дам альтернативу.

Member 12478311

Нет

Member 12478311

Спасибо.

3 Ответов

Рейтинг:
26

Karthik_Mahalingam

попробовать это

DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            dt.Columns.Add("ID");
            dt.Columns.Add("Name");
            for (int i = 1; i <= 200; i++)
                dt.Rows.Add(i, "Name - " + i);
            ds.Tables.Add(dt);

            DataTable dt1 = new DataTable();
            DataTable dt2 = new DataTable();

            dt1 = ds.Tables[0].Clone();
            for (int i = 0; i < 100; i++)
                dt1.Rows.Add(dt.Rows[i].ItemArray);

            dt2 = ds.Tables[0].Clone();
            for (int i = 100; i < 200; i++)
                dt2.Rows.Add(dt.Rows[i].ItemArray);

            DataSet ds1 = new DataSet();
            DataSet ds2 = new DataSet();
            ds1.Tables.Add(dt1); 
            ds2.Tables.Add(dt2);


Member 12478311

Спасибо

Karthik_Mahalingam

добро пожаловать

Maciej Los

Ну... я действительно считаю, что давать кому-то готовое к использованию решение-плохая идея, но иногда это лучшая идея...
А5!

Karthik_Mahalingam

Спасибо Мацей
:)

Рейтинг:
12

njammy

1. В вашем коде сохраняйте переменные startIndex, pageSize и totalRows.
2. На инициализации, установите значение параметра startindex = 0.
3. Установите pageSize по умолчанию, например pageSize = 10 или все, что вы хотите/пользователь хочет.
4. Установите currentPage на 1.
5. Установите totalRows для записи количества записей из результата запроса.
6. Возьмите количество исходных строк и скопируйте их в целевую таблицу
См. пример кода (извините за многословие, но я использовал веб-сайт dotNetFiddle, чтобы попробовать его для вас).
7. все, что вам нужно сделать, это указать текущую страницу, и она получит строки для этого диапазона.

Примечание:это будет не очень хорошая производительность на больших наборах. Используйте LINQ или переместите логику подкачки, показанную здесь, на сторону базы данных, используя параметры и временную таблицу, чтобы получить столбцы идентификатора ссылки.

using System;
using System.Data;
using System.Collections.Generic;
using System.Xml;
					
public class Program
{
	private static DataTable dt;
	private static DataTable refDt;
	private static int startIndex;
	private static int pageSize = 5;
	private static int currentPage = 3;
	private static int totalRows;
	private static int totalPages;
	
	
	public static void Main()
	{
		// Simulating a query result data bind.
		dt = new DataTable("MyDataTable");
		dt.Columns.AddRange(new DataColumn[]
							{
								new DataColumn("col1"),
								new DataColumn("col2"),
								new DataColumn("col3")
							});
		List<object[]> data = new List<object[]>
		{
			new object[] { "1.1", "1.2", "1.3" },
			new object[] { "2.1", "2.2", "2.3" },
			new object[] { "3.1", "3.2", "3.3" },
			new object[] { "4.1", "4.2", "4.3" },
			new object[] { "5.1", "5.2", "5.3" },
			new object[] { "6.1", "6.2", "6.3" },
			new object[] { "7.1", "7.2", "7.3" },
			new object[] { "8.1", "8.2", "8.3" },
			new object[] { "9.1", "9.2", "9.3" },
			new object[] { "10.1", "10.2", "10.3" },
			new object[] { "11.1", "11.2", "11.3" },
			new object[] { "12.1", "12.2", "12.3" },
		};
		
		foreach(object[] dataItems in data)
		{
			dt.Rows.Add(dataItems);
		}
		
		// Now do the paging:		
		totalRows = dt.Rows.Count;
		
		// Set up a reference table to track ids as the source DT may be sorted etc and spoil the tracker field.
		refDt = new DataTable("RefDt");
		refDt.Columns.AddRange(new DataColumn[]
							   {
								   new DataColumn("Index"),
								   new DataColumn("Id")
							   });
		for(int i=0;i<dt.Rows.Count;i++)
		{
			// Here, the refDt data table is built up to store a reference to each ID field in source datatable
			// along with a row number
			refDt.Rows.Add(new object[] {Convert.ToString(i), dt.Rows[i]["col1"]});
			//Console.WriteLine("Index:" + refDt.Rows[i].ItemArray[0] + ", Id:" + refDt.Rows[i].ItemArray[1]);
		}
		
		
		// Now lets work out how many to take and copy to destination data table
		DataTable dest = new DataTable("Destination");
		dest = dt.Clone(); // <- copys columns/schema but not data.
		
		
		startIndex = (currentPage * pageSize) - pageSize;
		Console.WriteLine("Reading " + pageSize + " rows starting at row index " + startIndex);
		
		
		for(int i = startIndex; (pageSize * currentPage) > totalRows ? i < totalRows : i < pageSize * currentPage; i++)
		{
			string lookupFilter = "Index = '" + i.ToString() + "'";
			DataRow dr = (DataRow)refDt.Select(lookupFilter)[0];	
			
			string id = Convert.ToString(dr[1]);
			string selectFilter = "col1 = '" + id + "'";
						
			DataRow source = dt.Select(selectFilter)[0];
			
			dest.Rows.Add(source.ItemArray);
			
			// Just to prove it only copies the required range
			string output= "";
			for(int c = 0; c < dest.Columns.Count; c++)
			{
				output += Convert.ToString(dest.Rows[dest.Rows.Count-1][c]) + ", ";
			}
			Console.WriteLine(output.Remove(output.Length-2,2));
		}
		
		int remainderRows = dt.Rows.Count % pageSize;
		totalPages = remainderRows > 0 ? totalRows/pageSize + 1: totalRows/pageSize;
		Console.WriteLine("Last page has " + remainderRows + " rows");
		Console.WriteLine("Page " + currentPage + " of " + totalPages  + " (Total " + dt.Rows.Count + " rows)");
	}
}


Maciej Los

Ну... я действительно считаю, что давать кому-то готовое к использованию решение-плохая идея, но иногда это лучшая идея...
А5!

njammy

Так мы все чему-нибудь учимся.

Рейтинг:
11

Maciej Los

Проверьте прошлый ответ: Как разделить данные из одного Datatable на два отдельных Datatable?[^]

Другой способ-использовать Linq to DataSet[^]:

int j =0;
for(int i==0;i+=100;i<200)
{
    //get 100 records
    var copy = ds.Tables[0].AsEnumerable().Skip(i).Take(100);
    //CopyToDataTable method is used to copy data into another datatable
    ds.Table[j] = copy.CopyToDataTable();
    j+=1;
}


Для получения более подробной информации, пожалуйста, ознакомьтесь с документацией MSDN: Создание DataTable из запроса (LINQ to DataSet)[^]

Примечание:
1) для очень большого объема данных решение linq может вызвать проблемы с производительностью
2) структура данных назначения должна быть такой же, как и исходная


Karthik_Mahalingam

а 4, потому что в разделе комментариев он дал " нет "использовать " linq".

Хороший, упрощенный код по сравнению с вышеприведенным решением 2.

Maciej Los

Спасибо, Картик.
Ну... я не вижу "нет, чтобы использовать linq" даже в комментариях к вопросу и / или решениям. Как я уже упоминал, решение linq является алернативным. Я добавил две заметки, где одна из них говорит о возможных проблемах с производительностью при использовании linq.
Не поймите меня неправильно, я очень ценю Ваши 4.

Karthik_Mahalingam

Мацей,
чуть ниже вопроса-комментарий ньямми "Можете ли вы использовать Linq в своем решении? дайте мне знать. в противном случае я дам альтернативу.- и оп ответила :нет' для него.
для этого комментария только я дал 4, иначе это идеальное решение вопроса. Овации :)

Maciej Los

Оооо... Теперь я это вижу. Спасибо. Ура!

njammy

Я согласен, что это хорошо сделано для решения, тем не менее, однажды кто-то может прийти сюда и принять решение Linq, если на самом деле он сможет использовать его в своем решении.