Reading DataSet - c#

How do I read data from a DataSet in WPF? I have a train schedule table with just 2 columns and I want to be able to read the departure times and calculate when the next train is leaving. For example, the time now is 12:29 and my application should tell me that next train will depart at 12:33.
I already googled left and right. I'm on .NET 3.5.

DataSet resembles database. DataTable resembles database table, and DataRow resembles a record in a table. If you want to add filtering or sorting options, you then do so with a DataView object, and convert it back to a separate DataTable object.
If you're using database to store your data, then you first load a database table to a DataSet object in memory. You can load multiple database tables to one DataSet, and select specific table to read from the DataSet through DataTable object. Subsequently, you read a specific row of data from your DataTable through DataRow. Following codes demonstrate the steps:
SqlCeDataAdapter da = new SqlCeDataAdapter();
DataSet ds = new DataSet();
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());
}
To read a specific cell in a row:
int rowNum // row number
string columnName = "DepartureTime"; // database table column name
dt.Rows[rowNum][columnName].ToString();

If ds is the DataSet, you can access the CustomerID column of the first row in the first table with something like:
DataRow dr = ds.Tables[0].Rows[0];
Console.WriteLine(dr["CustomerID"]);

If this is from a SQL Server datebase you could issue this kind of query...
Select Top 1 DepartureTime From TrainSchedule where DepartureTime >
GetUTCDate()
Order By DepartureTime ASC
GetDate() could also be used, not sure how dates are being stored.
I am not sure how the data is being stored and/or read.

TL;DR: - grab the datatable from the dataset and read from the rows property.
DataSet ds = new DataSet();
DataTable dt = new DataTable();
DataColumn col = new DataColumn("Id", typeof(int));
dt.Columns.Add(col);
dt.Rows.Add(new object[] { 1 });
ds.Tables.Add(dt);
var row = ds.Tables[0].Rows[0];
//access the ID column.
var id = (int) row.ItemArray[0];
A DataSet is a copy of data accessed from a database, but doesn't even require a database to use at all. It is preferred, though.
Note that if you are creating a new application, consider using an ORM, such as the Entity Framework or NHibernate, since DataSets are no longer preferred; however, they are still supported and as far as I can tell, are not going away any time soon.
If you are reading from standard dataset, then #KMC's answer is what you're looking for. The proper way to do this, though, is to create a Strongly-Typed DataSet and use that so you can take advantage of Intellisense. Assuming you are not using the Entity Framework, proceed.
If you don't already have a dedicated space for your data access layer, such as a project or an App_Data folder, I suggest you create one now. Otherwise, proceed as follows under your data project folder:
Add > Add New Item > DataSet. The file created will have an .xsd extension.
You'll then need to create a DataTable. Create a DataTable (click on the file, then right click on the design window - the file has an .xsd extension - and click Add > DataTable). Create some columns (Right click on the datatable you just created > Add > Column). Finally, you'll need a table adapter to access the data. You'll need to setup a connection to your database to access data referenced in the dataset.
After you are done, after successfully referencing the DataSet in your project (using statement), you can access the DataSet with intellisense. This makes it so much easier than untyped datasets.
When possible, use Strongly-Typed DataSets instead of untyped ones. Although it is more work to create, it ends up saving you lots of time later with intellisense. You could do something like:
MyStronglyTypedDataSet trainDataSet = new MyStronglyTypedDataSet();
DataAdapterForThisDataSet dataAdapter = new DataAdapterForThisDataSet();
//code to fill the dataset
//omitted - you'll have to either use the wizard to create data fill/retrieval
//methods or you'll use your own custom classes to fill the dataset.
if(trainDataSet.NextTrainDepartureTime > CurrentTime){
trainDataSet.QueueNextTrain = true; //assumes QueueNextTrain is in your Strongly-Typed dataset
}
else
//do some other work
The above example assumes that your Strongly-Typed DataSet has a column of type DateTime named NextTrainDepartureTime. Hope that helps!

Related

Datagridview with two datasources

I have two tables one is them main table contains (id, Date, TestID, Result)
and the orther is a lookup table (TestID, TestName)
I want to show data like this in datagridview:
Id , Date, Test 1, Test 2, Test 3, Result.
and to be able to save it, is this possible? and how to start
Perhaps you could combine the data from each of your datasources into a single dataset and then assign that dataset as the source of your dataview. However, without further info it's hard to speculate on possible solutions.
However ..
You can combine your resultsets into one DataTable using two SqlDataAdapter to fill the DataTable from the two databases respectively. Here is an example.
DataTable dt = new DataTable();
using(SqlDataAdapter a1 = new SqlDataAdapter("SELECT * FROM [user1]", "Data Source=DBServer1;Initial Catalog=Database1;User ID=user;Password=***"))
a1.Fill(dt);
using(SqlDataAdapter a2 = new SqlDataAdapter("SELECT * FROM [user2]", "Data Source=DBServer2;Initial Catalog=Database2;User ID=user;Password=***"))
a2.Fill(dt);
***ABOVE IS JUST EXAMPLE its not the 100% correct method to do it starting with the connection to the Database , but its something for you to start and think about it ****
a1.Fill(dt) will initialize the DataTable and fill it. a2.Fill(dt) just adds rows to the DataTable dt from the other resultset. This example assumes that the two data sources have the same schema. If not, you have to prepare the datatable to accomodate both resultsets.
Hope this helps.
Certainly, the relationship between the records of first table by the second table need to a shared columns. For example, tables have ID column and it's shared between table one and two, so best way is JOIN tables on two DataTables or Merge by DataTable.Merge Method on .NET.
Other way is, Concatenates two sequences by Enumerable.Concat Method
References:
How to: Concatenate Two Sequences (LINQ to SQL)
DataTable.Merge Method (DataTable)

OleDbDataAdapter Sporadic Missing Records

In my application I'm getting some data out of a local MS Access database file. I'm puzzled by a sporadic issue where my query for all records of a specific table sometimes returns all the records, and sometimes returns all but the last record. I'm using the following code
string resourceConStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data source = C:/FileName.mdb";
OleDbConnection resourceCon = new OleDbConnection(resourceConStr);
OleDbDataAdapter personnelAdapter = new OleDbDataAdapter("Select * From Personnel", resourceCon);
DataTable personnel = new DataTable();
personnelAdapter.Fill(personnel);
When I look at the personnel DataTable, sometimes I have the correct # of records and sometimes I'm missing the last record from the Access table. I haven't been able to find any pattern as to when it works successfully and when it does not. Any idea what could be the reason for this or suggestions or a way to validate that all records were copied into the DataTable sucessfully? Thanks
Any ... suggestions or a way to validate that all records were copied into the DataTable sucessfully?
One way to do it would be to execute a SELECT COUNT(*) AS n FROM Personnel, and compare that number (assuming that you get one back) with the number of rows in the DataTable after it gets filled.

Deleting values from dataset

I am trying to delete the data present in the dataset with following code:
stateflowDataSet dsobject = new stateflowDataSet();
stateflowDataSetTableAdapters.dbo_statetableTableAdapter statetableadapter = new stateflowDataSetTableAdapters.dbo_statetableTableAdapter();
statetableadapter.Fill(dsobject.dbo_statetable);
dsobject.dbo_statetable.Clear();
statetableadapter.Update(dsobject);
But after this line when use statetableadapter.Fill(dsobject.dbo_statetable); the data is still retained.
Is the way in which I am clearing the data right?
Is there any other problem with the code?
Removing DataRows from a DataTable does not mean that you'll delete them from your DBMS. The opposite is true, actually you're preventing them from being deleted even if you would have called DataRow.Delete() before.
The reason is: only DataRows that belong to a DataTable can be deleted by
DataAdapter.Update(table)
This will delete every row in the table with DataRowState=Deleted.
Therefor you need to use the Delete method.
foreach(DataRow row in dsobject.dbo_statetable.Rows)
{
row.Delete();
}
statetableadapter.Update(dsobject.dbo_statetable);
You could do it also in one batch which would be more efficient, therefor you need to set the DataAdapter's UpdateBatchSize to 0(unlimited).
Another way would to delete all rows is to use a simple SqlCommand with CommandText DELETE FROM Table:
using(var con = new SqlConnection(ConfigurationSettings.AppSettings["con"]))
using(var cmd = new SqlCommand())
{
cmd.CommandText = "DELETE FROM Table";
cmd.Connection = con;
con.Open();
int numberDeleted = cmd.ExecuteNonQuery(); // all rows deleted
}
Now you need to remove(not delete, what is the core of your question) the rows from the DataTable manually since you've also deleted them manually in the database:
dsobject.dbo_statetable.Clear();
Let me try re-wording Tims answer a little. I used DataSets alot when they were popular, and was confused with their 'magic'...
Dataset contains copy of the data from the database + your updates on the data since data is fetched from the database.
Update() method on the DataAdapter with your dataset isn't magic, it goes through your tables in the dataset, and in tables it scan rows. It will:
use DeleteCommand if row is marked for deletion
use UpdateCommand if row is marked for update
Former is the case when you delete a row with Delete() method, and later is the case when you update some cell in the row.
You will learn much about the process if you observe RowState property of each row in the dataset tables.

How can I select what columns come in from a DataSet into a DataTable?

Being new to working with Data, I hope I'm asking this properly. How can I select what columns come in from a DataSet into a DataTable? I know I can fill a DataTable by using...
DataTable table = dataSet1.Tables[0];
but this brings in all the columns. How can I fill a DataTable with only certain columns?
I'm using .NET 3.5, C#, and a SQL CE 3.5 single table database.
Thanks.
The DataTable is actually filled via a DataAdapter when the DataSet is created. Once you run your query, the columns in the DataTable are set. But, you can use a DataView to apply an additional filter and a column reduction to a DataTable, but the cost of querying the database and pulling data has already occurred, so you should consider making sure your query doesn't pull back more than you need. MSDN is a great resource.
Of course if you're just now learning this, it bears mentioning that while ADO.NET is important to know foundationally, you should be aware that there's a lot of momentum away from raw ADO.NET lately towards things like Entity Framework. While SQL will never die, nor should it, you're going to have to write a whole lot more plumbing code when using ADO.NET then you would with a nice ORM. Check out these posts for more info.
// Assumes that connection is a valid SqlConnection object.
string queryString = "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
DataTable table = customers.Tables[0];
Instead of "CustomerID, CompanyName" you can put the columns you want to select.
For further learning check this MSDN link.

I want to create an access database populated with data from xml file

I want to create an Access database('mdb') from an xml file.
Creating empty access database is easy(I am able to do this), I am having problem in figuring out how can we create a table and populate it with data from the xml file on the fly through code.
I am using C#.
You can read the XML file into a DataSet, then populate it into your database.
DataSet ds = new DataSet();
ds.ReadXml(filename);
foreach(DataTable table in ds.Tables) {
//Create table
foreach(DataRow row in table.Rows) {
//Insert rows
}
}
That's a fairly simple outline below.
How are you connecting to the MDB file?
Via ADO/OLEDB you will need to issue SQL-DMO instructions such as "CREATE TABLE"
If you are using DAO via COM Interop, you can create the table programmatically via the Database.TableDefs collection.
In either case you will need to know your data types / mapping, unless you are using entirely text fields in the tables.
DataSet ds = new DataSet();
ds.ReadXml(filename);
foreach(DataTable table in ds.Tables) {
//Create table
foreach(DataRow row in table.Rows) {
//Insert rows
}
}
Is there a reason you're doing this programmaticly instead of using the built in feature?

Categories