ok now i am using the SQL database to get the values from different tables... so i make the connection and get the values like this:
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings["XYZConnectionString"].ConnectionString;
connection.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT * FROM Machines", connection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
sqlCmd.Parameters.AddWithValue("#node", node);
sqlDa.Fill(dt);
connection.Close();
so this is one query on the page and i am calling many other queries on the page.
So do i need to open and close the connection everytime...???
also if not this portion is common in all:
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings["XYZConnectionString"].ConnectionString;
connection.Open();
can i like put it in one function and call it instead.. the code would look cleaner...
i tried doing that but i get errors like:
Connection does not exist in the current context.
any suggestions???
thanks
You can definitely share the "open connection" code, no reason to duplicate it.
With the SQL Server provider for ASP.NET, there is very little overhead with "closing" the connection every time. It just returns the connection to your process' connection pool (see here), so opening the next connection will use very little overhead. I think it is good practice to close the connection after each operation
I use "using". You can include as many queries as you like inside. When complete it will clean up for you.
using (SqlConnection cn = new SqlConnection(connectionString))
{
using (SqlCommand cm = new SqlCommand(commandString, cn))
{
cn.Open();
cm.ExecuteNonQuery();
}
}
Typically yes, you make individual connections for multiple rowsets.
If you can use joins to produce a single meaningful rowset, that's typically a good thing to do on the server side instead of the client side.
You may also want to look at making multiple connections and using the async features in order to queue all your requests simultaneously instead of sequentially - have a look at this article.
No you do not have to open and close the connection every time as long as you are using the same database. What you need to change is the
sqlCommand's queryString every time.
Like what #durilai said, [using] is useful. Using actually has more functions than this, but essentially it puts a try/catch block around your code and calls dispose to close the connection in this case.
Anything that needs open/close can be used with using, so things such as text writers, or other objects.
Related
I have a stored procedure that I need to run in C# and set the result set returning from the SP in a HTML table. Please note that the SP is working well in SSMS and returning results.
The c# code I am using is (it is in an ASP 4.5 project):
SQLDatabase sqldb = new SQLDatabase();
using (SqlConnection sqlcn = new SqlConnection(sqldb.GetConnectionString().ToString()))
{
if (sqlcn.State == ConnectionState.Closed)
{
sqlcn.Open();
}
SqlCommand cmd = new SqlCommand("[MyStoredProcedure]", sqlcn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#FromDate", Convert.ToDateTime(txtFrom.Value.ToString()));
cmd.Parameters.AddWithValue("#ToDate", Convert.ToDateTime(txtTo.Value.ToString()));
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
a.Fill(ds);
dtExtra = ds.Tables[0];
}
}
This code above is returning 0 rows, even though the SP is working in SSMS. While debugging, the connectionstring and the parameters are coming all true, no issue. The connectionstring is:
<add name="DefaultDB" connectionString="Data Source=TestEnv;Initial Catalog=TestTable;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
I don't understand what may cause this. I found the topic below, but I am using Integrated Security=SSPI in my connection string already, so it did not help me. Any advice would be appreciated.
ASP.NET stored proc call bringing back no rows, but does in Management Studio!
EDIT: SOLVED! Thanks #NineBerry. It turned into a between/and usage problem in SP. Changing txtTo.Value as: DateTime.Today.AddDays(1).ToString("yyyy-MM-dd"); in the code fixed the issue (It was DateTime.Today.ToString("yyyy-MM-dd") before, I should have included it in the code part, didn't think it is related to that, sorry). Better solution would be updating the SP using >= and <= instead of between/and keywords tho.
I would modify your code to simply be:
using(var dbConnection = new SqlConnection("..."))
using(var command = new SqlCommand(query, dbConnection))
{
dbConnection.Open();
...
}
Handling the connection pooling in the using block is always a good idea per Microsoft guideline:
To ensure that connections are always closed, open the connection
inside of a using block, as shown in the following code fragment.
Doing so ensures that the connection is automatically closed when the
code exits the block.
You are checking if the connection is closed, what if the connection is idle? By using the using syntax you implement dispose. So it will correctly close your connection, so you should not need to check if the connection is closed unless you are using a singleton for the connection.
After reading your question, you may have more than just the one issue I pointed out. I would recommend a service account with access the specific data you are seeking, that the application can access rather than integrated security.
I would like to know what custom code (not EF) the experts use to get data from SQL Server in .NET / C#. I have been using methods like this:
public static DataTable SelectAllForNavigation()
{
using (SqlConnection sqlConn = new SqlConnection(Config.ConnStr))
{
try
{
SqlCommand sqlCmd = new SqlCommand("spr_Web_Content", sqlConn);
sqlConn.Open();
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add("#Op", SqlDbType.VarChar, 100).Value = "SelectAllForNavigation";
SqlDataReader sqlDr = sqlCmd.ExecuteReader(CommandBehavior.CloseConnection);
DataTable dt = new DataTable();
dt.Load(sqlDr);
sqlDr.Close();
sqlDr.Dispose();
return dt;
}
catch (Exception)
{
return null;
}
}
}
It works and I don't see an overhead in SQL Server when hammering requests for data, but recently I have modified the method to this:
public static DataTable SelectAllForNavigation()
{
try
{
using (SqlConnection sqlConn = new SqlConnection(Config.ConnStr))
{
using (SqlCommand sqlCmd = new SqlCommand("spr_Web_Content", sqlConn))
{
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add("#Op", SqlDbType.VarChar, 100).Value = "SelectAllForNavigation";
sqlConn.Open();
using (SqlDataReader sqlDr = sqlCmd.ExecuteReader(CommandBehavior.CloseConnection))
{
DataTable dt = new DataTable();
dt.Load(sqlDr);
return dt;
}
}
}
}
catch (Exception)
{
return null;
}
}
Similar, but with 2 major differences; using using wrappers and placed a try/catch around the whole thing to try to catch any potential connection issues as well.
My questions are:
Is this new method that much better from an efficient perspective?
Where should the sqlConn.Open() be placed in the code?
Do I still need the CommandBehavior.CloseConnection in the SqlDataReader now that its wrapped with a using?
Any better way to do this, efficiently?
Is this new method that much better from an efficient perspective?
No, in terms of performance, the two approaches are probably almost identical. But your "new", second approach is much better in terms of maintainability and safety - it ensures that objects like SqlCommand etc. are freed as soon as possible.
Where should the sqlConn.Open() be placed in the code?
Just before you execute the query is really the best place for this - the connection really doesn't need to be open while you're doing all your setup work ....
Do I still need the CommandBehavior.CloseConnection in the SqlDataReader now that its wrapped with a using?
It's still a good idea, yes - even if the using block will also close the connection (when disposing the SqlCommand), I always find doing so explicitly in my own code is even better (and certainly doesn't hurt).
Any better way to do this, efficiently?
In terms of developer productivity : use Entity Framework to get rid of having to write all that gooey code - but if you insist on using low-level ADO.NET, that's about as good as it gets.
I would recomend you to use SqlDataAdapter and DataTable. In this you don't need to Open and Close connection explicitly.
Also in your current approach you are getting data in SqlDatareader and than loading in DataTable so you are creating an extra object which will occupy memory.
Using SqlDataAdadpter approach is called Disconnected or ConnectionLess while using SqlDataReader is called Connection Oriented approach.
Difference is that in ConnectinoOriented approach you need to Open and Close connection manually also connection should remain open until you are reading data. In other approach you can read data even connection is closed.
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
using(SqlCommand cmd = new SqlCommand("select * from testtable where id=#id", con));
{
adapter = new SqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("#id", 1);
adapter.Fill(dt);
}
}
Is this new method that much better from an efficient perspective?
I don't think so. As far as I see, only difference between your methods is using of using statement and this method does not make your method more efficient. It provides an auto mechanism disposing for IDisposable objects.
Where should the sqlConn.Open() be placed in the code?
Just before when you need an open connection. In your fist case, I would use it just before SqlDataReader sqlDr = sqlCmd.ExecuteReader(CommandBehavior.CloseConnection) line since I only need first time to an open connection.
Do I still need the CommandBehavior.CloseConnection in the
SqlDataReader now that its wrapped with a using?
It is still a better approach to use it. For example, if your code throws an exception on it and if you don't use CloseConnection, your code won't access the contents of your reader. Also, using CloseConnection may harm your code little bit based on this thread.
Any better way to do this, efficiently?
That depends a lot of things but if you use them in small project, ADO.NET will be efficient as well but I generally use EF as much as I can.
First of all, as I read in ur description, that u hammer in requests. So I assume u talk about alot of frequent requests. If this occurs, i highly recommend to not close ur sql connection after each query. This will speed up ur method actually a lot, because ur application doesn't need to communicate, handshake, and ... for every single query.
Is this new method that much better from an efficient perspective?
Using is actually nothing to do with performance. It's actually a helper for the developer, and to keep the Garbage Collection cleaner. Using does nothing else then calling the Object.Dispose() as using needs an IDisposable Object to work. So u don't have to deal with closing and disposing the connection. So performance grant equals to zero.
Where should the sqlConn.Open() be placed in the code?
If u keep in mind my first answer, u should establish the connection somewhere in the loading of ur window.
Do I still need the CommandBehavior.CloseConnection in the SqlDataReader now that its wrapped with a using?
No. If ur interested in what is using doing MSDN
Any better way to do this, efficiently?
See my first post. The rest of the actual query can't be boosted, because it's actually just building the query, and sending it to the server and finally retreiving it.
Ok, I'm settling for this solution:
try
{
using (SqlConnection sqlConn = new SqlConnection(Config.ConnStr))
using (SqlCommand sqlCmd = new SqlCommand("spr_Web_Content", sqlConn))
{
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add("#Op", SqlDbType.VarChar, 100).Value = "SelectAllForNavigation";
sqlConn.Open();
using (SqlDataReader sqlDr = sqlCmd.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(sqlDr);
return dt;
}
}
}
catch (Exception)
{
return null;
}
It seems to provide the best performance and efficiency. I just have a couple more doubts before I wrap this topic and move on;
Do I save memory be returning a DataRow as opposed to a DataTable with 1 row?
I keep seeing using (var sqlConn = ... is this same as using (SqlConnection sqlConn = ...?
Thanks.
I am using the JOB to continuously watch the table data. Inside the JOB i am calling the SQLCLR SP. SQLCLR SP will run. Before the while loop i will open the SQL connection. Inside for loop i will access the database 1000-10000 times in only one connection. I wont close the DB connection untill my work is done.
SqlConnection connection = null;
try
{
using (connection = new SqlConnection("context connection=true"))
{
connection.Open();
DataTable dt;
SqlDataAdapter adp=new SqlDataAdapter("select * from tableName",CnStr);
DataSet ds=new DataSet();
adp.Fill(ds,"TableName");
dt= ds[0];
//dt.Rows.count may be range from 1000-10000
for(i=0;i<dt.Rows.count;i++)
{
int id = int.Parse(dt.Rows[i][0].ToString());
SqlCommand command = new SqlCommand("select * from table1 where IsParsed=0 and Id=" + id, connection);
SqlDataReader r1 = command.ExecuteReader();
SqlCommand command = new SqlCommand("Insert into table2 (values)", connection);
int r2 = command.ExecuteNonQuery();
//Always get table1 data which has IsParsed=0. Get those rows manipulate those rows data and
// insert into datatable table2 and update those rows to IsParsed=1
SqlCommand command = new SqlCommand("Update table1 set IsParsed=1 where id=#id", connection);
int r3 = command.ExecuteNonQuery();
// Run the Billing Logic here
// Insert into Billing Table
SqlCommand command = new SqlCommand("Insert into Billing(values)", connection);
int r2 = command.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
}
finally
{
connection.close();
}
Is there any problem with this approach let me know? Is there any issue with using the connection like this? Provide proper suggestion..
I gone through the article
better way to Execute multiple commands in single connection
Here I am using the Context Connection and executing the thousands of command in single connection. Is there any consideration of Connection pool in context connection..? How about the performance of single command execution for each connection vs multiple command execution with single connection?
Also I want to know that in both cases like context connection and regular connection yields to same result? because the SP is deployed in DB itself. If I wrong please correct me.
There is no problem in executing large number of queries over a single connection. Any how you are using a SQL CLR Procedure with context connection. As mentioned in MSDN it states that:
using the context connection typically results in better performance and less resource usage. The context connection is an in-process–only connection, so it can contact the server "directly" by bypassing the network protocol and transport layers to send Transact-SQL statements and receive results. The authentication process is bypassed, as well.
Please refer this link for more information on context and regular connection.
No. It is fine to execute a large number of queries over a single connection.
Your code would likely perform worse if you were to open/close a connection to run those three SQL queries for each of those 1000+ rows.
I have a bit of .NET code that retrieves the results from an Oracle Stored Procedure, using the ADO.NET Library, and populates the results into a DataTable like so:
using System.Data.OracleClient;
public DataTable getData()
{
OracleConnection conn = new OracleConnection("Data Source=DATASOURCE;Persist Security Info=True;User ID=userID;Password=userPass;Unicode=True;Min Pool Size=1;Max Pool Size=20;Connection Lifetime=300");
DataTable dt = new DataTable();
conn.Open();
try
{
OracleCommand oraCmd = new OracleCommand();
oraCmd.Connection = conn;
oraCmd.CommandText = "stored_procedure.function_name";
oraCmd.CommandType = CommandType.StoredProcedure;
oraCmd.Parameters.Add("cursor", OracleType.Cursor).Direction = ParameterDirection.Output;
OracleDataAdapter oraAdapter = new OracleDataAdapter(oraCmd);
oraAdapter.Fill(dt);
}
finally
{
conn.Close();
return dt;
}
}
This code has been working without any issues on several projects I have implemented the code on. However I am running into an issue on a new project, where the Oracle DB machine is actually much slower to respond, and seems to become unresponsive when too many clients begin to access the hardware. What I would like to do is implement some sort of timeout on the oraAdapter.Fill command - as it appears that when the database becomes unresponsive, the .NET application will hang on the 'Fill' method for as long as 10 minutes or more, never reaching the 'finally' codeblock and closing the DB connection.
I am in an environment where I am restricted to using the MSDN Library for connecting to the Oracle Database, so I'm hoping I can do it using the ADO.NET Control.
The CommandTimeout property does not work using the System.Data.OracleClient .NET 3.5 Provider. It appears that this functionality is not supported without the use of an external library.
It seems you need the CommandTimeout property, not ConnectionTimeout.
Basically, I would like a brief explanation of how I can access a SQL database in C# code. I gather that a connection and a command is required, but what's going on? I guess what I'm asking is for someone to de-mystify the process a bit. Thanks.
For clarity, in my case I'm doing web apps, e-commerce stuff. It's all ASP.NET, C#, and SQL databases.
I'm going to go ahead and close this thread. It's a little to general and I am going to post some more pointed and tutorial-esque questions and answers on the subject.
MSDN has a pretty good writeup here:
http://msdn.microsoft.com/en-us/library/s7ee2dwt(VS.71).aspx
You should take a look at the data-reader for simple select-statements. Sample from the MSDN page:
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
}
It basicly first creates a SqlConnection object and then creates the SqlCommand-object that holds the actual select you are going to do, and a reference to the connection we just created. Then it opens the connection and on the next line, executes your statements and returns a SqlDataReader object.
In the while-loop it then outputs the values from the first row in the reader. Every time "reader.Read()" is called the reader will contain a new row.
Then the reader is then closed, and because we are exiting the "using"-secret, the connection is also closed.
EDIT: If you are looking for info on selecting/updating data in ASP.NET, 4GuysFromRolla has a very nice Multipart Series on ASP.NET 2.0's Data Source Controls
EDIT2: As others have pointed out, if you are using a newer version of .NET i would recommend looking into LINQ. An introduction, samples and writeup can be found on this MSDN page.
The old ADO.Net (sqlConnection, etc.) is a dinosaur with the advent of LINQ. LINQ requires .Net 3.5, but is backwards compatible with all .Net 2.0+ and Visual Studio 2005, etc.
To start with linq is ridiculously easy.
Add a new item to your project, a linq-to-sql file, this will be placed in your App_Code folder (for this example, we'll call it example.dbml)
from your server explorer, drag a table from your database into the dbml (the table will be named items in this example)
save the dbml file
You now have built a few classes. You built the exampleDataContext class, which is your linq initializer, and you built the item class which is a class for objects in the items table. This is all done automatically and you don't need to worry about it. Now say I want to get record with the itemID of 3, this is all I need to do:
exampleDataContext db = new exampleDataContext(); // initializes your linq-to-sql
item item_I_want = (from i in db.items where i.itemID == 3 select i).First(); // using the 'item' class your dbml made
And that's all it takes. Now you have a new item named item_I_want... now, if you want some information from the item you just call it like this:
int intID = item_I_want.itemID;
string itemName = item_I_want.name;
Linq is very simple to use! And this is just the tip of the iceberg.
No need to learn antiquated ADO when you have a more powerful, easier tool at your disposal :)
Reads like a beginner question. That calls for beginner video demos.
http://www.asp.net/learn/data-videos/
They are ASP.NET focused, but pay attention to the database aspects.
topics to look at:
ADO.NET basics
LINQ to SQL
Managed database providers
If it is a web application here are some good resources for getting started with data access in .NET:
http://weblogs.asp.net/scottgu/archive/2007/04/14/working-with-data-in-asp-net-2-0.aspx
To connect/perform operations on an SQL server db:
using System.Data;
using System.Data.SqlClient;
string connString = "Data Source=...";
SqlConnection conn = new SqlConnection(connString); // you can also use ConnectionStringBuilder
connection.Open();
string sql = "..."; // your SQL query
SqlCommand command = new SqlCommand(sql, conn);
// if you're interested in reading from a database use one of the following methods
// method 1
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
object someValue = reader.GetValue(0); // GetValue takes one parameter -- the column index
}
// make sure you close the reader when you're done
reader.Close();
// method 2
DataTable table;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
// then work with the table as you would normally
// when you're done
connection.Close();
Most other database servers like MySQL and PostgreSQL have similar interfaces for connection and manipulation.
If what you are looking for is an easy to follow tutorial, then you should head over to the www.ASP.net website.
Here is a link to the starter video page: http://www.asp.net/learn/videos/video-49.aspx
Here is the video if you want to download it: video download
and here is a link to the C# project from the video: download project
Good luck.
I would also recommend using DataSets. They are really easy to use, just few mouse clicks, without writing any code and good enough for small apps.
If you have Visual Studio 2008 I would recommend skipping ADO.NET and leaping right in to LINQ to SQL
#J D OConal is basically right, but you need to make sure that you dispose of your connections:
string connString = "Data Source=...";
string sql = "..."; // your SQL query
//this using block
using( SqlConnection conn = new SqlConnection(connString) )
using( SqlCommand command = new SqlCommand(sql, conn) )
{
connection.Open();
// if you're interested in reading from a database use one of the following methods
// method 1
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
object someValue = reader.GetValue(0); // GetValue takes one parameter -- the column index
}
// make sure you close the reader when you're done
reader.Close();
// method 2
DataTable table;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
// then work with the table as you would normally
// when you're done
connection.Close();
}