How to access data in a DataSet within current project? - c#

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());
}

Related

Display DataTable content in ReportViewer

I've heard that the best way to print a DataTable is to use ReportViewer. However I found it more difficult to achieve this than I thought. I am not familiar with ReportViewer, so perhaps I want to find a solution that is non-existent.
"reportView" is the ReportViewer control.
//I am creating a fresh new DataTable here.
DataTable reportDT = new DataTable();
reportDT.TableName = "reportDT";
DataColumn dataColID = reportDT.Columns.Add("ID");
DataColumn dataColValue = reportDT.Columns.Add("Value");
DataRow newrow = reportDT.NewRow();
newrow["ID"] = string1;
newrow["Value"] = string2;
reportDT.Rows.Add(newrow);
//Until now, this works perfectly with DataGridView.
//I am creating a new source object, hopefully from my datatable.
ReportDataSource source = new ReportDataSource("reportDT", reportDT);
reportView.ProcessingMode = ProcessingMode.Local;
reportView.LocalReport.DataSources.Add(source);
this.reportView.RefreshReport();
Running the app like this throws no exception, but it shows no data in the reportview either. It says: "The source of the report definition has not been specified".
I have realized that it might need a .rdlc file, which must be created design time. But if I create it design time, it wants me to fill it with data, which I cannot do, because the data is created runtime. So I want to display a bunch of data in ReportViewer, but the above code does not work. What is wrong with it?
You need to create a report file. The reportViewer1 is a Control, not a Report and therefore cannot display data directly.
To avoid repeating code, your answer can be found here.

UPDATING Dataset Fails?

According to this article : http://msdn.microsoft.com/en-us/library/xzb1zw3x.aspx , after I insert/change data in the dataset, I need to call the UPDATE to synchronize my database data with the dataset data.
My problem is this:
I have created a dataset called dataset1.xsd and then I create a new TableAdapter to do my INSERT query with, and THEN I need to somehow let my database know that the stuff in dataset has changed.
DataSet1TableAdapters.reservationsTableAdapter ta = new DataSet1TableAdapters.reservationsTableAdapter();
ta.Insert(LastName,Arrival,Departure); // this is where I do the INSERT query
Now I should update the dataset, right? How do I do this? The article I posted above suggests doing something like this:
ta.Update(DataSet1.reservationsDataTAble);
However, I can't do this because:
Error - 'myproject.DataSet1.reservationsDataTable' is a 'type', which is not valid in the given context.
I tried declaring a new Dataset1 DataTable, and then updating that, but it still won't show any changes in my database.
I KNOW, however, that the changes are saved in the DataSet, because when I fill a new datatable later, the record is there.
EDIT: Thanks to the comments, below, I tried doing this for a change:
DataSet1.reservationsDataTable NDT = new DataSet1.reservationsDataTable();
DataSet1TableAdapters.reservationsTableAdapter ta = new DataSet1TableAdapters.reservationsTableAdapter();
ta.Insert(LastName,Arrival,Departure);
ta.Fill(NDT);
ta.Update(NDT);
... and I could see (in the debugger) that the NDT datatable DID in fact contain the data that was "INSERTED" and then filled into the data table.
However, the ta.Update(NDT); still did not update my database...
I assume that However, the ta.Update(NDT); still did not update my database means that no sql-insert is executed and that yo get no exception.
does this work for you?
var myDataSet1 = new DataSet1();
var newReservation = myDataSet1.reservations.NewRow();
newReservation.LastName=...
newReservation.Arrival=...
newReservation.Departure=...
myDataSet1.reservations.AddreservationsRow(newReservation);
var ta = new DataSet1TableAdapters.reservationsTableAdapter();
ta.Update(myDataSet1.reservations);

Is that possible to bind two dataset at a same time in crystal report?

Is that possible to bind two dataset at a same time in asp.net crystal report?
I tried the code below, but it asks for server details:
Invoice inv = new Invoice();
inv.OrgId = Session["org_id"].ToString();
inv.InvoiceId = invoiceId.ToString();
ds = _reportController.ReportPrintBillView(inv);
dtBill=ds.Tables[0];
dtInvoice = ds.Tables[1];
ReportDocument myRpt = new ReportDocument();
myRpt.Load(Server.MapPath("PrintandprintBill.rpt"));
myRpt.SetDatabaseLogon("root", "root", "localhost", "hemaepdb");
myRpt.SetDataSource(dtBill);
myRpt.SetDataSource(dtInvoice);
CrystalReportViewerPrint.ReportSource = myRpt;
CrystalReportViewerPrint.Visible = true;
No, the report accepts one datasource. However your subreports may have a different datasource.
EDIT:
If you need data from two different datasets that have similar data you might try to combine the data into one dataset. Even if some of the data duplicates, you can then create groups and use the suppress functionality to only show and format the data in the way you need to see it. See my answer here for a better explanation of the grouping and suppressing that I am referring to.
From ur Requirement i think u want to use View. View is one kind of logical table that maps other columns from different tables. And at Datable just use View Name and add this datatable to dataset. simply SetDataSource to dataset.

C# SQL Data Adapter Fill on existing typed Dataset

I have an option to choose between local based data storing (xml file) or SQL Server based.
I already created a long time ago a typed dataset for my application to save data local in the xml file.
Now, I have a bool that changes between Server based version and local version. If true my application get the data from the SQL Server.
I'm not sure but It seems that Sql Adapter's Fill Method can't fill the Data in my existing schema
SqlCommand cmd = new SqlCommand("Select * FROM dbo.Categories WHERE CatUserId = 1", _connection);
cmd.CommandType = CommandType.Text;
_sqlAdapter = new SqlDataAdapter(cmd);
_sqlAdapter.TableMappings.Add("Categories", "dbo.Categories");
_sqlAdapter.Fill(Program.Dataset);
This should fill my data from dbo.Categories to Categories (in my local, typed dataset).
but it doesn't. It creates a new table with the name "Table". It looks like it can't handle the existing schema.
I can't figure it out. Where is the problem?
btw. of course the database request I do isn't very useful that way. It's just a simplified version for testing...
The Fill overload you are using, passing in a DataSet will always create a NEW DataTable in the supplied DataSet with name "Table" (MSDN).
So, I think you either need to change your TableMapping to:
_sqlAdapter.TableMappings.Add("Table", "Categories");
(MSDN) assuming your DataTable name is "Categories".
Or, don't use TableMappings and just supply the second argument - the name of the DataTable in that DataSet you want to populate (MSDN). The approach I usually use is actually to pass the DataTable itself that you want to populate, instead of the DataSet (MSDN).
Try _sqlAdapter.TableMappings.Add("Table", "Categories");, but as i remember you will have to add column mapping also. btw, you can try to create typed dataadapter, it is useless thing, but you can take mapping from there.

Merging Multiple ADO.NET DataSets

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.

Categories