Which DataSet creation technique is faster? - c#

Which one of these techniques is faster?
1)
DbDataAdapter dataAdapter = _factory.CreateDataAdapter();
dataAdapter.SelectCommand = _command;
dataSet = new DataSet();
dataAdapter.Fill(dataSet);
2)
DataTable dt = new DataTable();
IDataReader iDataReader= _command.ExecuteReader();
dt.Load(iDataReader);
iDataReader.Close();

Have a look at these links
DataReaders, DataSets, and performance
and
DataAdapter.Fill preferable to DataReader?
As mentioned in the comments to your question. It would be best to test for the given situation at hand, there is never a one rule applies to all.

Related

`DataTable` does not contain a definition for 'Fill' - c#

I am not understanding why I am getting an error after reading documentation in regards to the .Fill(). Am I missing something that is causing this to return with an error?
protected void FillData()
{
using (SqlConnection connection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename= C:\Users\home\Documents\C# Programs\shop\Database.mdf ;Integrated Security = True"))
{
connection.Open();
using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from Employee", connection))
{
DataTable table = new DataTable();
table.Fill(table);
employeeDataGridView.DataSource = table;
}
}
}
The problem is in this line of code
table.Fill(table);
You can't use table, to fill your table. The correct syntax would be
dataAdapter.Fill(table)
You can't populate a DataTable in that way, you need to fill your DataAdapter, use a DataSet and then set the DataGridView to use this.
using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from Employee", connection))
{
var ds = new DataSet();
dataAdapter.Fill(ds);
employeeDataGridView.DataSource = ds.Tables[0];
}
The neatest way to code this up is:
protected void FillData()
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from Employee", #"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename= C:\Users\home\Documents\C# Programs\shop\Database.mdf ;Integrated Security=True"))
{
DataTable table = new DataTable();
dataAdapter.Fill(table);
employeeDataGridView.DataSource = table;
}
}
It'll get neater if you put your connection string in a static "global" variable somewhere
Points of note:
use the dataadapter constructor that takes two strings - it will create the connection and the command for you
you don't need to open the connection for the adapter- it knows how to
this means you can have just one using
if your sql needs parameters put them inside the using as dataAdapter.SelectCommand.Paramaters.Add...
you could turn this into a method that accepts any sql string and parameter collection and returns you a datatable
consider putting a WHERE clause in your sql; users might not like to see a grid with 20,000 employees in because it makes it harder to edit a handful of employees
It would be better to add a DataSet to your project (right click project, add>>new item, choose dataset - it gives you something that looks like a db visual design surface you can add queries to, create datatables that become components that can be added to your forms/create databound controls automatically) and create strongly typed datatables and table adapters
An alternative better route than this would be to use Dapper and strongly typed POCOs

SqlDataAdapter.Fill() vs DataTable.Load()

I come from this question here but I have a different case. I need my result in a DataTable and I have 2 potential methods:
public static DataTable SelectDataTable(string query, string ConnectionString)
{
using (SqlConnection myConnection = new SqlConnection(ConnectionString))
{
using (SqlDataAdapter myDataAdapter = new SqlDataAdapter(query, myConnection))
{
DataTable dt = new DataTable();
myDataAdapter.Fill(dt);
return dt;
}
}
}
and
public static DataTable SelectDataTable(string query, string ConnectionString)
{
using (SqlConnection myConnection = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(query, myConnection))
{
myConnection.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));
return dt;
}
}
}
so my question: is there difference between
SqlDataAdapter + Fill()
and
SqlDataReader + DataTable + Load()
Which of there methods is to prefer?
Joel answer is pretty detailed, what makes this question not a duplicate
In fact I don't use all those mentioned advantages of the SqlDataReader I use it to fill a DataTable and that makes me expecting the answer be like: It's the same?! Unfortunately it's hard to guess what's happening under the hood.
Unless you are working with big data, I wouldn't expect huge performance gains from using a dataReader as opposed to a dataAdapter.
That being said, the link Pawel posted has a pretty decent write-up explaining the differences and advantages of both.
The main takeaway is readers are for reading data. They do nothing else really than that.
Because they don't do much else, they are relatively low overhead for performance.
DataAdapters are going to allow you to do more than the Readers, but in your case, it sounds like you don't need to do anything other than read in the records.
To reiterate, unless you are working with big data (like hundreds of thousands/millions of rows) I wouldn't expect the performance savings by using the dataReader to be very noticeable.
That is something only you will be able to determine when benchmarking with your own data.
Let us know if that clears up any confusion you may have had about the differences between DataAdapter and DataReader.

C# + SQL Select + dataset + dataadapter = out of memory

I'm currently trying to use C# to read through an SQL DB. To do so, I use OleDB with a select statement. This goes into a dataset, which then populates a data adapter. I then iterate through each row and calculate stuff.
First of all, I feel like there's a better/more efficient way of doing this because I NEVER actually write back to the SQL DB. I just calculate based on what I'm selecting.
Anyways, past a certain point I get out of memory errors and/or an error from Ssms.exe saying "a new guard page for the stack cannot be created."
From the other questions I've seen, I need to use DataReader but I can't seem to get it to work the same way as the data adapter (which I suppose isn't that surprising).
The code I have now:
OleDbConnection myConn = new OleDbConnection(#"SQLDB connection string here");
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = <selectstatement here>
cmd.Connection = myConn;
cmd.CommandTimeout = 0;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
myConn.Close();
foreach (DataTable table in ds.Tables)
{
foreach (DataRow dr in table.Rows)
{
//do stuff
I guess my question is twofold, like I said above. One would DataReader solve my problem and allow me to iterate through the data, and two how do I adapt the first code snippet above to support that?
Also, since I've seen it elsewhere, I'm using x64 on the application.

Fill() Method becomes slow in .net (ADO)

In my .net application am facing a performance problem. One of my Stored procedure dealing with more than two tables having 30,000 records. But the SP itself returns fastly. but in my DataAccesss it will take more time for fill that into DataTable
My datataccess is
cmd.CommandType = CommandType.StoredProcedure;//cmd-sqlcommand object
conn.Open();//conn-sqlconnection object
adpt = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adpt.Fill(dt);
conn.Close();
return dt;
If any body know the solution for better performance please share.

Trying to load a DataSet, but it is always null. Regular sqlReader.GetValue() is not

I don't use DataSets much. Usually find myself using an ORM or just a basic sqlReader.Read() followed by some GetValues(). I'm working on some legacy code that has DataSets all over the place, and while fixing a bug was trying to DRY some of it up.
However, I can't seem to actually get the data loaded into a non-typed DataSet.
public static DataSet ExecuteStoredProcedure(string storedProcedure, DBEnum db, IEnumerable<SqlParameter> parameters)
{
DataSet result = new DataSet();
using (SqlConnection connection = SqlHelper.GetSqlConnection(db))
{
SqlCommand command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = storedProcedure;
if (parameters != null)
foreach (SqlParameter parameter in parameters)
command.Parameters.Add(parameter);
connection.Open();
DataTable table = new DataTable();
using (SqlDataReader reader = command.ExecuteReader())
{
table.Load(reader);
}
result = table.DataSet; // table.DataSet is always empty!
}
return result;
}
I assumed table.Load(reader) does all the necessary reader.Read() calls ... but I went ahead and tried it both with and without reader.Read() before the table.Load(), to no avail.
I know that the stored procedure being called is actually returning data. If I do something like this, I see the data just fine:
using(SqlDataReader reader = command.ExecuteReader())
{
reader.Read();
object test = reader.GetValue(0); // returns the expected value
}
Seems like I'm missing something simple here, but I've been scratching my head over this one for a while now.
This is in .NET 3.5.
If you can, I would suggest using a SqlDataAdapter to populate the DataTable
using(SqlDataAdapter sqlDA = new SqlDataAdapter(command))
{
sqlDA.Fill(table);
}
You logic shows the DataTable being loaded with data from the reader but DataTable is never added to a dataset.
I believe the dataset should be created first. In fact, you could use DataSet.Load instead of the DataTable.Load. The DataSet.Load should create data tables, but it won't work the other way around.
A DataSet contains DataTables not the other way round. So if you want to create a DataSet to return then you'll probably want to create a new dataset and then add your DataTable into it before returning it. If a DataTable is not in a DataSet then the reference to its parent dataset will always be null.
That having been said I do also recommend Jason Evans' suggestion of using teh SqlDataAdapter.
Think of a dataset as a collection of tables and optionally information about the relationships between them.
In your example code you are creating an independent Table that does not belong to a DataSet. To pragmatically create a table that is part of a dataset you could do the following:
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add();
//or
ds.Tables.Add(MyAlreadyCreatedTable);
Jason Evans above is also correct, populating DataTables and DataSets is much simpler using SqlDataAdaptors as he demonstrated.
Finally, the Method as you have it written is meant to return a DataSet. But it only captures a single result set from the stored procedure it is calling. It's possible that a procedure could return any number of separate results.
All you should need to do is change the following:
DataTable table = new DataTable();
using (SqlDataReader reader = command.ExecuteReader())
{
table.Load(reader);
}
to
//you can skip creating a new DataTable object
using (SqlDataAdapter da = new SqlDataAdapter(command))
{
da.Fill(result); // the result set you created at the top
}

Categories

Resources