I'm having a bit of difficulty with datasets in C#. I know how to load datasets and everything, and I can drag a table from the dataset into the form window and it displays the columns etc of that table. However, I would like to display every single table in the form, but in a clean way. Is there a way to create a dropdownlist for example, that will display all the tables in the data set, and then I can select the one I want and then display the columns, etc? Just need a way to display tables in the form and navigate between them and have them display their data. How would I go about doing this?
First of all you need to create an instance of DataSet (typed dataset) (say DatabaseDataSet)
DatabaseDataSet ds = new DatabaseDataSet();
Then create adapter's instance which is an autogenerated class.
DatabaseDataSetTableAdapters.yourTableTableAdapter adp;
adp=new DatabaseDataSetTableAdapters.yourTableTableAdapter();
Pupulate the datatable object and push into to ds.
adp.Fill(ds.yourTable);
Use DataBinding technique to show data from the dataset object.
comboBox1.DataSource = ds.Tables["yourTable"];
comboBox1.DisplayMember = "column1";
comboBox1.ValueMember = "column2";
Off-topic:Use Collections, LINQ and Entity framework. The DataSet is bit outdated and it has many problems. Please take a look at this MSDN post.
DataSets vs. Collections
Related
I create a small program using a SQL Server database and C#.
I connected to the database and sort all data and display it in a datagridview1 without any problems.
My code:
enter image description here
i otrzymuje wynik:
enter image description here
Now my question: how can I add a new column in datagridview1 with a completely new sort of SQL Server database data?
obviously a sort order is part of a SQL expression and you do not mean that, as you would surely already know (?) instead change how it sorts, which is the collation of the column. This is thankfully fully supported:
https://learn.microsoft.com/en-us/sql/relational-databases/collations/set-or-change-the-column-collation?view=sql-server-ver15
There are a few ways how to do it:
Make a complex SQL Query, that will group the data as it's needed, using Joins and other ways of data union.
The easiest and the worst way how to do it - is to extend your data table manually:
dataTable.Columns.Add(new DataColumn("newColumn", typeof(string)));
This will automatically refresh DataGridView on the form. And then you will need to add new data to the new DataTable column manually.
I prefer to work with dataGridView based on models. You need to create a class - that will represent your model. Like class Person with properties: Name, Age, etc. And then set this list as data source.
List<Person> listOfPersons = new();
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = new BindingSource() { DataSource = listOfPersons};
The main problem - you will need to parse database data to the model format.
Actually, this is where ORM (Object-Relational Mapping) is helpful. There are a few ready solutions, like Dapper. It will simplify your life)
basic question - is it possible to populate a combobox with datasource and then cut the link to the datasource, but keep the data in the combobox? this will enable you to reuse your ds.Tables[0] below without affecting the first populated combobox.
comboBox1.DataSource = ds.Tables[0];
(The ds is populated from MS SQL Server with SqlDataAdapter)
No, it is not possible without copying the source data in some way. The DataSource property is a reference to your dataset, datatable or whatever object not a copy of it. Setting DataSource to null will remove any possibilities for the combo to see the data referenced.
Instead you could easily create a copy of your original table using the appropriate method available in the DataTable class
comboBox1.DataSource = ds.Tables[0].Copy();
This create a new copy of the table with the actual structure and content, but it is a copy in another memory area of the informations stored in the first object. At this point you have two distinct objects in memory and you can change the first one without affecting the second.
Let me say also that this is not very smart with big tables. Don't use this approach if your table contains a lot of records for obvious reasons.
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.
I have a DataSet with multiple DataTables that I'd like to bind to a chart with multiple column series. I expected each series to have different values respective to the DataTables in the DataSets; however, when the chart appears, both series display the same values in the Y column, the values from the first tables.
Here is a general idea what my code is like:
(I created and filled up a DataSet named diffCharts, diffCharts contains tables table1 and table2, both tables have columns Month and Amount)
Chart1.Series.Add("table1");
Chart1.Series["table1"].XValueMember = "Month";
Chart1.Series["table1"].YValueMembers = "Amount";
Chart1.Series.Add("table2");
Chart1.Series["table2"].XValueMember = "Month";
Chart1.Series["table2"].YValueMembers = "Amount";
Chart1.DataSource = diffCharts;
Chart1.DataBind();
Am I missing something? I've never bound a DataSet with multiple tables to a chart before.... Does MS know how to handle this?
I know this is an old post, but better late than never.
You can bind enumerable data sources directly to the DataPointCollection property in the series using the DataBind method. This way each series can be bound to a different table.
I am relatively new to C#, so there may be an adverse affect to this method that I am not aware of. It functions correctly in my limited testing.
MSDN link.
Chart1.Series.Add("table1");
Chart1.Series["table1"].Points.DataBind(table.AsEnumerable(), "nameofXaxis", "nameofYaxis, "nameofPropertyaxis");
Propertyaxis can be left as an empty string
I don't think you can do that.
You'll probably need to create a table with one column as the shared column for the X Axis (Month) and then two more columns for the Y values you want to graph.
The DataTable class has a Merge function that may do exactly what you need.
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