OleDbDataAdapter Sporadic Missing Records - c#

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.

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)

How to copy large datatable to MySql table?

I am trying to copy a large datatable (columns with more than 1000 rows) created dynamically in the applicaiton to a MySQL table using c#, WPF.
I have searched for various ways to do this but was unsuccessful to implement. I think the MySqlDataAdapter class is something I should use but I cant make it work. This is what I tried to do...
MySqlConnection con = new MySqlConnection(MyConString);
MySqlCommand comm = new MySqlCommand("Select * From kinectdata", con);
MySqlDataAdapter test1 = new MySqlDataAdapter(comm);
test1.Update(skelData);
Speed of this transfer is also important so I prefered not to call an insert or update statement 1000 times.
Many thanks for your feedback!
M
You can build a single INSERT statement which inserts all 1000 rows.
INSERT INTO table VALUES (1,2,3), (4,5,6), (7,8,9);
1000 rows is not that much, in database terms its nothing, using insert should be very fast. No more then 2 seconds.
In your example you do have to declare command type and set your query and command text.

SqlDataAdapter.Fill() - Conversion overflow

All,
I am encountering "Conversion overflow" exceptions on one of the SqlDataAdapter.Fill() usages for a decimal field. The error occurs for value beginning 10 billion, but not till 1 billion. Here is the code:
DataSet ds = new DataSet();
SqlDataAdapter sd = new SqlDataAdapter();
adapter.SelectCommand = <my SQL Command instance>
adapter.Fill(ds);
I have read using SqlDataReader as an alternate but we need to set the datatype and precision explicitly. There are at least 70 columns that I am fetching and I don't want to set all of them only for one decimal field in error.
Can anyone suggest alternate approaches?
Thank you.
Although dataset is allowed for "filling" a data adapter, I've typically done with a DataTable instead as when querying, I'm only expecting one result set. Having said that, I would pre-query the table, just to get its structure... something like
select whatever from yourTable(s) where 1=2
This will get the expected result columns when you do a
DataTable myTable = new DataTable();
YourAdapter.Fill( myTable );
Now that you have a local table that will not fail for content size because no records will have been returned, you can now explicitly go to that one column in question and set its data type / size information as you need...
myTable.Columns["NameOfProblemColumn"].WhateverDataType/Precision = Whatever you need...
NOW, your local schema is legit and the problem column will have been identified with its precision. Now, put in your proper query with proper where clause and not the 1=2 to actually return data... Since no actual rows in the first pass, you don't even need to do a myTable.Clear() to clear the rows... Just re-run the query and dataAdapter.Fill().
I haven't actually tried as I don't have your data issues to simulate same problem, but the theoretical process should get you by without having to explicitly go through all columns... just the few that may pose the problem.
I had the same problem and the reason is because in my stored procedure I returned a decimal(38,20) field. I changed it into decimal(20,10) and all works fine. It seems to be a limitation of Ado.Net.
CREATE PROCEDURE FOOPROCEDURE AS
BEGIN
DECLARE #A DECIMAL(38,20) = 999999999999999999.99999999999999999999;
SELECT #A;
END
GO
string connectionString ="";
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("EXEC FOOPROCEDURE", conn);
SqlDataAdapter adt = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adt.Fill(ds); //exception thrown here

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.

Reading DataSet

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!

Categories