How do I Access separate pages of DataTable rows - c#

I have a DataTable with a large resultset.
This DataTable is used to generate multiple pages in a PDF (one for each row in the DataTable).
After a certain number of rows, the PDF generation takes too long, so I want to provide a list of hyperlinks for the end user to generate separate PDFs for each set of rows, i.e. Set 1 (Rows 0-90), Set 2 (Rows 91-181), etc.
I want to be able to filter the original DataTable whenever I generate a PDF for that set of rows. I know that GridViews offer Paging capability, but I don't want to plop the data into a gridview unnecessarily.
What I am hoping for is some kind of RowFilter where I can say:
_dt.RowFilter = "Rows(0-90)"
Does anyone know of such a feature of DataTables (using .NET 3.5)?
Or can anyone offer another solution?
Thanks

Try this - use the AsEnumerable extension method, then use LINQ to query the rows you need.
dataTable.AsEnumerable().Take(90);
Page 2:
dataTable.AsEnumerable().Skip(90).Take(90);

Related

How to read the header row (assuming first row is header) in excel without loading entire excel file

I am combining multiple large excel files with different columns and number of columns.
Before starting to combine, I want to collect all header rows in order to make a data table which having all columns in advance.
I know that there is a method datatable.merge in c#, which allow to add missing column while combining.
Because there are too many big excel files, and the maximum rows per sheet in excel is about 1 millions row. So when reaching limit, I must save part of combining to excel, clear the content and keep combine after that. This will lead to the result that the saving part in the early process will don't have the same schema as the final one.
This is the reason why I must collect all header in advance.
As far as I am concerned, library in c# like Epplus or ExcelDataReader load entire content of excel. This lasts very long. I don't need to load all content at once.
Somebody here know how to load excel header row only ?
Thank you so much.

Limit rows displayed in DataGridView when using DataSource

I have a DataTable containing 10000+ rows, resulting from a SQL Server query. The DataTable is used as the DataSource for a DataGridView, like so (simplified code):
MyBindingSource = New BindingSource(MyDataTable, Nothing)
MyDataGridView.DataSource = MyBindingSource
As this takes a looong time to load, I would like to limit the number of rows displayed in the DataGridView, somehow.
I can't use TOP in my query, because I need all the data present in the DataTable for filtering later on, without re-setting the DataSource (MyBindingSource.Filter = MyFilter).
Also, I can't use the Filter property for limiting the number of rows, because there's no relevant data in the query result that I can use for this. To get around this, I've thought about adding TSQL's ROW_NUMBER to the query result (MyBindingSource.Filter = "[RowNumberField] < 100"), but this would only work when no other fields are used in the filter.
Any ideas?
Here are a two options:
I would simply implement pagination on all of your views (filtered or unfiltered) using this technique of using a BindingNavigator GUI control which uses a BindingSource object to identify page breaks.
You can also filter by more than one criteria by using an OR operator but I don't see how that helps you with your current approach because your row numbers will have to be recalculated after each filter e.g. [RowNumberField] < 100 might return 100 rows with no filter by only 10 after a filter.
What you could do is move the filtering logic to your SQL query and then always show only the first X rows based on the row number (which I assume you are dynamically adding each time using TSQL's ROW_NUMBER()).
The advantage to this approach is that you can perform much more powerful filtering in TSQL and it keeps you Data Source smaller.
If you do take this approach, be careful about mixing your queries in with your view logic - I would recommend the Repository Pattern.

How to share DataTable between multiple Datagridviews across Application and save precious memory

I have a list of companies in DataTable format which is static and accessible across my application.
Different Forms in the application just show filtered Data like Customer Companies ,Supplier Companies ,Misc etc in a DataGridView.
The DataGridViews are just for the sake of displaying the Data.
If I query my companies DataTable for only customer companies and assign the result to DatagridView.Datasource, it will just make a copy and assign it DataGridView.
Imagine if I have a list of 10,000 Customers and User open 10 forms for different purpose, I will be just duplicating 10,000 * 10 rows of data.
Also if my main Companies DataTable is Updated , I will have to update all the DataGridViews too.
Will using DataViews help me save the memory ?
Will BindingDatasource do good?
or is there any better method to share DataTable without making copies in memory for just Displaying Purpose.
Regards
Given:
I have a list of companies in
DataTable format which is static and
accessible across my application
I assume 1 DataTable. You should use RowFilter see MSDN: RowFilter:
DataGridView customerView;
DataGridView supplierView; // initialize in form
DataTable companiesTable; // initialized and filled
void SetCustomerCompanyView()
{
DataView cust = new DataView();
cust.Table = companiesTable;
cust.RowFilter = "Type = 'Customer'";
customerView.DataSource = cust;
}
// repeat for SetSupplierCompanyView()
If the concern is that one large DataTable is going to be copied throughout multiple active views, then you should really re-think the architecture. If a form is hidden or inactive, you can always dispose of the query results (in worst case) and re-query if/when the form becomes visible or active again (such as a tabbed form). For what it's worth, 10k records is easily handled in most systems and should accommodate several open views (filtered as above) of that DataTable.
An overtly simplistic comparison:
You can think of a DataView as a List<int> where int would be a row index. When you apply a row filter, the appropriate row indexes are appended to the List. You could easily create a view using LINQ to DataSets - extracting the row indexes you require based on a column or columns of data and append to the List. Now you use that list to reference only the rows (by Table.Rows[RowIndex]) in which you are interested from your primary DataTable.As stated, this is much simpler functionality than what the DataView is actually providing. You have not made a copy of the DataTable - you have simply created a shallow reference mechanism.

how to limit rows in dataGridView?

i have a data file(csv) consisting of 2 columns & 1000 rows, as i load it to my datagridview it takes alot of time, i just want to show only the first 6 rows just as a preview of file to user. Is there any way i can show only the first 6 rows in my datagrid view. Following is the code im displaying the data in DataGridView.
DataTable csvDataTable = CSVReader.ReadCSVFile(textBoxCsv.Text, true);
dataGridViewCsvData.DataSource = csvDataTable;
dataGridViewCsvData.SelectionMode = DataGridViewSelectionMode.FullColumnSelect;
CSVReader is an open source project isn't it? try to add ReadTopLines method to that class that will read only top N lines given as parameter
Every datatable has it's own DefaultView.
http://msdn.microsoft.com/en-us/library/system.data.datatable.defaultview.aspx
You can then get the Table from the view by DefaultView.GetTable. And you can manipulate data in you View the way you want. You can filter up, query.
You can find out more about expressions here:
http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx
OR, since CSVReader is an open-source project, you can simply change
public DataTable CreateDataTable(bool headerRow)
Add number of lines to this method, and you will get what you need without reading the whole file.
I didn't read the whole source, so there might be a solution without even changing a code.
Use Open Source for 100%. Change it, customize it, send you patches! People do appreciate it! And you will get experience, knowledge and new friends who might help you in future :)

VC# 2008: Get Table names from DataTable into ComboList / How to merge tables from 2 MDBs?

My program that I am writing's purpose arose with this issue:
There are two users, each user saves to a .MDB file. One user has half the updated / correct information (the other half is outdated) and the other user has half the information (the other half is outdated).
User1: 25% + 25% = 50% current information needed the other 50% is outdated
User1 works on 2 out of the 4 items.
User2: 25% + 25% = 50% current information needed the other 50% is outdated
User2 works on 2 out of the 4 items.
I need to take that 50% (2 out of the 4 items) from lets say...User1 and add it to User2 making it 100% current (4 out of 4 items).
Their SQL style table structure is (should be anyways) identical (but if possible I would like to provide an event where for some a new table was added I would know)
If I could find out how to get all the table names from the DataTable, I could systematically array through the DataTable and replace the tables with the tables from the other .MDB file that I know need to be updated. I know DataSet has "DataSet.Tables" ...but that doesn't help me very much.
If I can do that, I can also add the tables to a combo box and create functionality to where whatever the combo box says, thats the table I will list on my Datagrid.
If any of you have any ideas on how to go about doing this (or if you even understand what i'm saying) please let me know. I'm 70% done with ths project, and these seem to be my last logic road blocks. I think I explained this right.
How do I list just the Table names
in a DataTable object.
What are your ideas on taking specific Tables out of a .MDB file and adding them to another .MDB file?
How would I go about inputting a ComboList drop-down box that included all the tables names...when I changed the table name it would list those contents on a Datagrid.
Is there a way to list tables on a Datagrid, and when you click on a Table it lists the contents of that table (kind of like a Tree structure).
EDIT:
I think he is right! I think DataTables are just one table whereas DataSets are sets of Tables. With that in mind, how do I list all the tables in a .MDB file into a DataSet? That would fix my problem perfectly.
I thought that a DataTable object was only a single table and a DataSet was what contained one to many DataTables.
If you are looking for the actual name of your DataTable, that would be accessed through the DataTable.TableName property.
Edit: If you are wanting to add DataTables into a DataSet object, just create a new DataSet and then use the .Add() method.
Dim DS as new DataSet
Dim DT as new DataTable("TableName")
DS.Add(DT)
You should then be able to loop through your DataSet and retrieve table names by accessing each DataTable's TableName property:
For each table as DataTable in DS.Tables
Console.Writeline(table.TableName)
Next

Categories

Resources