I am trying to make a copy of a DataTable with a different TableName. I have used this in the past without issue and the code from the past works just fine today. When i try using the exact same code the table will add to the DataSet but there is no data or column names.
DataView dv = dataSet.Tables["Traveler"].DefaultView; /// the dataview is exactly like the datatable
DataTable Parts_Kit = dv.ToTable("Parts_Kit"); /// the new datatable has no data or columns
dataSet.Tables.Add("Parts_Kit"); /// Parts_Kit is added to dataset but completly blank
I have dorked around with this for 4 hours now with no results. What could i possibly be missing?
as per the definition of Add(string DataTable name), you are creating a new / blank table in dataSet that has nothing to do with the DataTable Parts_Kit.
As per MS documentation as well, you want to use,
dataSet.Tables.Add(Parts_Kit); // without quotes around Parts_Kit.
This will add the table you created from view (Parts_Kit) to the DataTableCollection, dataSet. To Test this as well, you can print Parts_Kit.TableName to see if it is the correct "Parts_Kit" name (from ToTable("Parts_Kit") command).
Related
I'm attempting to access a basic table from a local database in my Windows Forms project. I seem to have created the database correctly, and imported the dataset as expected as it displays in my Solution Explorer.
However, I am stuck on how to actually access the data within my database. I've attempted many different solutions but I cannot seem to get anywhere.
Here is what I've accomplished so far:
Solution Explorer Screenshot
But I cannot figure out how to make queries to the dataset, whether it's selecting, updating, or deleting rows.
The closest I've come to getting the data is from the code here:
InventoryDatabaseDataSet context = new InventoryDatabaseDataSet();
var inv = context.Tables["Inventory"];
var all = inv.Select();
But it doesn't return any seemingly valid data.
How do I go about making queries to my dataset? I understand Linq is the common method of making queries, but I don't understand how to get to the point of being able to do such a thing.
Any help would be greatly appreciated, thanks!
The DataSet item in the Solution Explorer represents a number of types. Just as String, Int32 and Form are types, so InventoryDatabaseDataSet is a type. Just like other types, you create an instance in code and then use it.
You will also find that those types that are components have been added to your Toolbox and can be added to forms in the designer, just like other controls and components.
You can also drag items from the Data Sources window and have the designer generate appropriate objects and code. For instance, if you drag a table from the Data Sources window to a form, it will generate a DataSet to store the data, a table adapter to retrieve data from the database and save changes back, a DataGridView to display the data, a BindingSource to link between the DataTable and the DataGridView and a BindingNavigator to navigate the data.
If you do use the designer then you'll see code generated to retrieve data by calling Fill on the table adapter and save changes by calling Update. If you want to do it in code yourself then you can do it something like this to retrieve:
var data = new InventoryDatabaseDataSet();
using (var adapter = new InventoryTableAdapter())
{
adapter.Fill(data);
}
this.InventoryBindingSource.DataSource = data.Inventory;
this.InventoryDataGridView.DataSource = this.InventoryBindingSource;
and this to save:
this.InventoryBindingSource.EndEdit();
var data = (InventoryDataTable) this.InventoryBindingSource.DataSource;
using adapter = new InventoryTableAdapter())
{
adapter.Update(data);
}
After storing data in DataSet,DataSet is read through DataTable object.
Similarly object of DataRow is used to read the row of a table.
Following is the sample code
InventoryDatabaseDataSet ds = new new InventoryDatabaseDataSet();;
DataTable dt = new DataTable();
da.SelectCommand = new SqlCommand(#"SELECT * FROM FooTable", connString);
da.Fill(ds, "FooTable");
dt = ds.Tables["FooTable"];
foreach (DataRow dr in dt.Rows)
{
MessageBox.Show(dr["Column1"].ToString());
}
Scenario
I have a c# winforms application with a gridview.
The gridview datasource is populated by a dataset.
The contents of this dataset get updated every few seconds, and there are not always the same number of items in the dataset etc.
The dataset actually gets populated (or needs to get populated) by multiple other datasets being passed in one at a time.These datasets update at completely random times that cannot be controlled.
The Issue
Since essentially the GridView dataset is being "CONTINUALLY UPDATED" - At the time of an update(The point that a new dataset with the latest information in it needs to be merged with the existing GridView DataSource), I need to take a copy of the current dataset populating the gridview, compare it to the incoming data from the other dataset and update ONLY the data that is new.
So Far
I've tried a series of different methods but I can't seem to get this to work. I either end up with the dataset just being added to continually with duplicates of slightly different data, or the rows randomly get deleted (I tried using a merge all then delete approach which only works occasionally).
Any ideas how I can get around this!?
At the moment the gridview just updates itself to show the latest incoming dataset without the previous dataset merged into it.....
CODE - This randomly deletes the rows even though it does at some points display all data
//If the existing GridView dataset contains any rows that
//exist in the incoming latest dataset (matched on the two unique fields
//of the dataset), then remove that row from the existing GridView dataset
for (int i = 0; i < existingPriceResultsDTCopyForCompare.Rows.Count; i++)
{
foreach (DataRow incomingRow in incomingDS.Tables[0].Rows)
{
string incomingDate = incomingRow["Date"].ToString();
DataRow currentRow = existingPriceResultsDTCopyForCompare.Rows[i];
if ((currentRow["CCY"].ToString().Contains(incomingCcy))
&& (currentRow["Date"].ToString().Contains(incomingDate)))
{
existingPriceResultsDT.Rows.RemoveAt(i);
}
}
}
//Then merge the existing GridView dataset (Minus the old data that
//matches the data from the incoming Dataset with the latest information),
//With the brand new incoming data.
incomingDS.Merge(existingPriceResultsDT);
EDIT -
I'm beginning to wonder if the incoming dataset keeps being overwritten by the next incoming dataset before the iteration has time to complete. So I'm guessing I need to lock the incoming DataSet?
Have you tried something similar
DataSet ds1 = new DataSet();
DataSet ds2 = new DataSet();
ds1.Merge(ds2);
DataSet ds3 = ds1.GetChanges();
As per your Objects
DataSet existingPriceResultsDT = new DataSet();
DataSet incomingDS = new DataSet();
incomingDS.Merge(existingPriceResultsDT);
existingPriceResultsDT = incomingDS.GetChanges();
You might want to look into the Microsoft Sync Framework. This sounds like a perfect scenario for it. This video is a good introduction. You can also download the tutorials here.
That nested for-loop stuff is a big-O nightmare. You definitely want to get out of the business of looping through those rows - lots of unnecessary compares.
It looks like you've got a couple of columns there that you are comparing each time - "CCY" and "Date". Have you considered using them as the primary key for the table? If that makes sense for your scenario, you can make things considerably more efficient.
You could consider doing something like this:
Determine which columns are primary keys - it appears here that CCY and Date are for you.
DataColumn[] keys = new DataColumn[2];
keys[0] = dataTable.column["CCY"];
keys[1] = dataTable.column["Date"];
dataTable.PrimaryKey = keys;
Then when you read in a new DataSet - however you do that, call Merge on it like so:
dataSet.Merge(newDataSet, false, MissingSchemaAction.Add);
Assumption here is that dataTable is the Tables[0] of dataSet.
This, at least for my quick test program, will merge the two DataSets and update the rows that changed and add any new ones.
And, I just had my DataGridView set up like so:
dataGridView1.DataSource = dataSet.Tables[0];
Seemed to update the view well enough for my test program.
Hope that helps.
The following code:
DataSet ds = new DataSet;
ds.ReadXml("c:\output\" + nome);
GridView1.DataSource = ds;
GridView1.DataBind();
succeeds in getting the fields from the XML, but as default it only displays the three first fields
(this XML specially may have about 60 fields, of which i wish to gather 3 or 4 of them)
how do i take off these fields and choose the fields that i want?
facts:
i know the names of the fields
i have unlimited space for the xml datagrid display
i don't need links or anything, just normal display of data
i'd like to know aso if there's a way of loading more than one xml into a datagrid (several rows)
answer either in c# or vb.net.. there's no problem
Done it.
Used data table as the binding.
in each column i chose the desired field and then in each row creating routine i got the data from the dataset just like i would normally:
Dim dt As DataTable = New DataTable()
Dim dr As Data.DataRow = Nothing
(... column creating...)
dr(0) = ds.Tables("<xml table>").Rows(0)("xml field>")
...
...
after everything, i just bind it to a gridview:
GridView1.DataSource = dt
GridView1.DataBind()
Thank you.
I've checked through the history of questions, hit google, and other results and still am completely baffled about the C# reportViewer. It appears to only want to work with "typed" datasets. As many other people have inquired and I saw no real answers, maybe a fresh post will pull something new.
In its simplest form, I have a business object that performs a query from a database. I know what the resulting columns are and want to have it plugged into a specific report that is properly "formatted" as I need, as opposed to a simple columnar dump.
Since the query returns a "DataTable" object, but no known columns are "typed", I'm hosed.
As mentioned in other posts, if I have a system of 200+ tables, 400+ views and 200+ stored procedures, I don't want to type-cast everything. Especially if I am doing a NEW query that is a result of individual tables joined from some NEW stored procedure.
It shouldn't be this difficult to draw a report. If I type the column wrong, or SUM(), COUNT(), or whatever incorrectly, that's my fault, but at least let me get an untyped table into a report.
Help...
The DataTable's columns don't need to be typed, they can all use the default of string.
What I did was I added a DataSet to my project, and designed the DataSet to match my query. I left all columns as strings. In the RDLC, I set up a table using this DataSet as my datasource, strictly for design time purposes.
At runtime, I instead dynamically swapped in a DataTable I generated and made sure it matched the design time DataSet (since they are all strings, I just need to make sure my DataTable has the same number of columns and the column names match).
DataTable dt = new DataTable();
DataColumn dc = dt.Columns.Add();
dc.ColumnName = "DataColumn1";
dc = dt.Columns.Add();
dc.ColumnName = "DataColumn2";
dt.Rows.Add(new object[] { "Frank", 32 });
this.reportViewer1.LocalReport.DataSources.Clear();
this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1_DataTable1", dt));
this.reportViewer1.RefreshReport();
At runtime the ReportViewer loads this DataTable as its data source and uses it to populate the table.
Is that what you are after?
I'm attempting to pull some data from a SQLite database so that I can populate a GridView in my GUI: here is the code that returns the DataTable:
DataTable table = new DataTable();
SQLiteDataAdapter adapter = new SQLiteDataAdapter(this.command.CommandText, this.connection);
adapter.Fill(table);
return table;
For some reason after calling adapter.Fill, the DataTable is still not populated with anything. So far I've verified that the command text is correct and that the connection contains the correct connection string. Both are used successfully in other parts of the application. No exceptions seem to be thrown... Is there any place else I should be looking for trouble? Am I using the API incorrectly?
Thanks!
This looks like correct usage.
One thing to check -- after the fill you say the datatable is not populated. Were you just checking Rows.Count? What about columns? If the Fill creates columns to match your SELECT statement, but there aren't any rows, then you know the code is working but there's a problem with either your query, or you're not hitting the same database you think you are.
Is there a constructor that lets you just pass in the command directly?