I'm basically trying to figure out the simplest way to perform your basic insert operation in C#.NET using the SqlClient namespace.
I'm using SqlConnection for my db link, I've already had success executing some reads, and I want to know the simplest way to insert data. I'm finding what seem to be pretty verbose methods when I google.
using (var conn = new SqlConnection(yourConnectionString))
{
var cmd = new SqlCommand("insert into Foo values (#bar)", conn);
cmd.Parameters.AddWithValue("#bar", 17);
conn.Open();
cmd.ExecuteNonQuery();
}
Since you seem to be just getting started with this now is the best time to familiarize yourself with the concept of a Data Access Layer (obligatory wikipedia link). It will be very helpful for you down the road when you're apps have more interaction with the database throughout and you want to minimize code duplication. Also makes for more consistent behavior, making testing and tons of other things easier.
using (SqlConnection myConnection new SqlConnection("Your connection string"))
{
SqlCommand myCommand = new SqlCommand("INSERT INTO ... VALUES ...", myConnection);
myConnection.Open();
myCommand.ExecuteNonQuery();
}
Related
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 have a C#/ASP.net project has included a database that I have developed that includes a nice and convenient View that would be handy to use.
I have the SQL connection setup to a SQL Server 2008 DB I created. It seems as though it is connecting fine, but I don't understand how to actually use the View that I created without hard coding the query into the program (been told this is bad sometimes?).
This is my connection I setup:
SqlConnection conn = null;
conn = new SqlConnection("Data Source=raven\\sqlexpress;Initial Catalog=ucs;Integrated Security=True;Pooling=False");
conn.Open();
SqlCommand command = new SqlCommand(query, conn);
Basically, I need some code to query using this View. I can see the View and look at the results that would be obtained, but not access it in the program!
The view is named "UserView". Help is much appreciated!
You could use something like the following. But it's usually considered evil to put hardcoded SQL commands into .Net code. It's much better and safer to use stored procedures instead.
This should get you started. You can modify it to use stored procedures by
changing the command.CommandType to indicate it's a stored proc call
And adding the proper parameters to the command that your SP needs.
Change command.CommandText to the name of your SP, thus
eliminating the hardcoded SQL.
sample code below:
using (SqlConnection connection = new SqlConnection("Data Source=raven\\sqlexpress;Initial Catalog=ucs;Integrated Security=True;Pooling=False"))
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * from your_view WHERE your_where_clause";
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// process result
reader.GetInt32(0); // get first column from view, assume it's a 32-bit int
reader.GetString(1); // get second column from view, assume it's a string
// etc.
}
}
}
}
Using VS2013 add a new DataSet to your project. Drag your View from the Server Explorer to the DataSet Design Surface.
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.
I want to load the entire database (SQL Server) I have into a dataset so that I can work with several tables and their relationships. I know this might be frowned upon, but how can I do this (I will be using DataRelation and Table objects)?
Thanks
Unless I'm missing something this should just be a simple case of generating a dataset and then altering the Fill methods to remove the WHERE portion. Then ensure you call the fills in the right order (master, then detail) to ensure you maintain the referential integrity.
You can run this... but don't expect to have a db or app server after.
using (SqlConnection conn = new SqlConnection("YourConnectionString"))
{
using (SqlCommand command = new SqlCommand("exec sp_msforeachtable 'select * FROM ?'", conn))
{
conn.Open();
DataSet ds = new DataSet();
command.Fill(ds);
}
}
Read some article about in memory Database.
# Randolph Potter idea is an option - you can get the list of tables from the server, and then iterate on the list and load all the tables. I guess you can do that same about FK and relations.
you can probably do it automatically using the designer - using drag and drop from the server explorer to a dataset (VS2008), and with a little code load the entire thing into memory.
I suppose you could do multiple selects within a single stored procedure and then fill a dataset.
using (SqlConnection conn = new SqlConnection("YourConnectionString"))
{
using (SqlDataAdapter command = new SqlDataAdapter("usp_YourStoredProcedure", conn))
{
command.CommandType = CommandType.StoredProcedure;
conn.Open();
DataSet ds = new DataSet();
command.Fill(ds);
}
}
I would agree with the other comments here that unless your database is tiny this is a really bad idea.
This is related to the Nested Database transactions in C#.
The objects in collection I want to take in transaction implement their own transactions using SqlConnection.BeginTransaction method.
After reading this post I am not sure if I can mix those too or not.
I am using SQL Server 2005 and each object uses connection details from static configuration class.
Does anybody have experience with this ?
Here is the sample code:
using(TransactionScope scope = new TransactionScope())
{
for (int i=0; i<=1000....)
{
SqlConnection con = new SqlConnection()
SqlCommand cmd = new SqlCommand("delete from ...", con);
try {
con.Open();
DbTransaction t = con.BeginTransaction();
cmd.ExecuteNonQuery();
...
cmd.CommandText = .... ;
cmd.ExecuteNonQuery();
t.Commit ...
}
catch {
t.Rollback ...
}
con.Close()
}
}
Thx
After spending hours to configure MSDTC to work on both machines, I finally got to the point where I could test the code.
It appears to work (with 1 database)
The above problem may be usefull to people that don't have access to the source code so can't get rid of "legacy" transactional system or if transactional parts of the code are not localised or, like in my case, you don't want to mess too much with the complex code that is proven to be stable in production environment but you need to introduce nested transactions...
Let me know if you have different experience.