Getting SQL Connection fragmentation, different way to connect to DB's - c#

We have multiple DB servers. On one of the servers we have a master config table that holds instructions as to what DB server and DataBase name an Agency is supposed to use.
Currently each Database always has 2 connections on them, even if they're not being used (which we are fixing). However, we're trying to find a way to make it so our connections are not all over the place, and relieve some of the stress on our DB Servers.
After a lot of research we found some articles saying to do all connections to a central location, and then Change which database we're using through the SQLConnection object. Which seems a bit roundabout, but could work.
So I'm wondering what others do in this situation?
The current path for this is:
-User Logs in
-System access ConfigTable to find out which database user is going to connect to.
-System loads the Agency connection settings into memory (SEssion) for that user.
-Every request now directly hits that users database.
Is there a more efficient way of doing this?

Open connections late, and close them early.
For example:
string result;
using (var con = new SqlConnection(...))
{
con.Open();
var com = con.CreateCommand();
com.CommandText = "select 'hello world'";
result = com.ExecuteScalar();
}
The Windows OS will make sure to efficiently pool and reuse connections. And since you're only using connections when you need them, there are no idle connections lying around.
EDIT: Windows only caches connection strings that are literally the same, so if you use Initial Catalog=<dbname> in the connection string, that could hurt performance by requiring 500+ "connection pools" for one server.
So if you have 4 servers with a lot of databases, make sure you only use 4 connection strings. After connecting, switch database with:
com.CommandText = "use <dbname>";
com.ExecuteNonQuery();
Or query with a three-part name like:
select * from <dbname>.dbo.YourTable

Related

C# Sql LocalDB Application Slow Performance

I am completely new sql/database applications and am trying out a simple contact management applicaton using Visual Studio 2015 C#. I am using 'SQL Express LocalDB'. I have read on google that it is meant for development purpose, but microsoft also mentions that it could be used for production purpose too.
My problem is that when I try out the application from my developement system, the application first time takes few seconds to load but after that every query runs quickly. When I tried this on one my friends system, it takes time everytime I try to use any query. The database is just with 20-30 records.
I create new connection using 'new SqlConnection' and then execute command created by 'new SqlCommand' and after executing query I close the connection.
Here is the code snippet from my app
SqlConnection sqlConnection = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename = ""C:\ContactsDB.mdf""; Integrated Security = True; Connect Timeout = 30";);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = sqlConnection;
sqlCmd.CommandText = "SELECT Id, first_name, last_name from ContactsMaster ORDER BY first_name";
sqlConnection.Open();
SqlDataReader reader = sqlCmd.ExecuteReader();
try
{
while (reader.Read())
{
ListViewItem lvi = new ListViewItem(reader["first_name"]);
listViewItems.Add(lvi);
lvi.SubItems.Add(reader[0].ToString());
}
}
finally
{
reader.Close();
}
sqlConnection.Close();
Q. Should I keep the connection open all the time while app is running? I don't think this should be suggested. As if app crashes database can get corrupt.
One of the backdrop which ppl saying that LocalDB closes the connection every new milliseconds. So should I keep pinging the database every few milliseconds? Or I should not use localdb in production at all?
I want to make the app such that the requirement goes really low regaridng the database prerequisites. Like LocalDB installation is really seamless.
I have not used SQL Server Express, does Express installation is also seamless like LocalDB and can I use the connection string like LocalDB in Express too, giving the .mdf filename directly?
localdb has auto shutdown. default is 5 min. you can set it to higher value (ie: 12hour).
max is 65535 min.
see: How to prevent SQL Server LocalDB auto shutdown?
also sqlexpress autoshutdown is 1hour if im not wrong.
symptoms on my pc:
first open is 10- 30 seconds slow. if i reopen app right after it is below 1 second. if i wait for a while it is slow again
There are many things to take in count for ddbb performance, it's not a simple question. For such small amount of records there shouldn't be performance problems. Try storing the ddbb files in another disk different from OS disk, and even better, place data file and log file in different disks too.
About your question, connections must be always closed and disposed properly in a finally block or inside a using block.
Sql Express is very easy to install, and also use a connection string, been the biggest difference that it can be used across the network.
Finally moved to SQLite and that is much faster in compare to SQLLocalDB.

Sharing SQL Server Between Multiple System

I have three computer in a office and I have installed my C#-2005 Project on all three
computers. But Problem is that Boss wants Sql-server-2000 on One PC out of three and other
would share the same.
I don’t know how to share Sql-server-2000 between three PC?. How to do?.
Confusion:-
Thanks for your co-operation but here I have a confusion on majority people said to check
TCP/IP address and consider the Connection string as per main server from client PC.
Suppose I have financial project and there would be thousand of connection string in a
project. As per above I have to change thousand of connection string as per main pc.
Now think it is a one customer's need If I have ten cutomer having same offer than think How much time I have to waste on it?. I have to modify thousand of connection string ten time more?.
If it is true than it will take lots of time on installation to each customer.
I don’t know if it is only way?.
The Connection string I have utilized on my each winform is as below:
string connstr = "server=.;initial catalog=maa;uid=mah;pwd=mah";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
Here suggested about Config File and same I don't know if some body give me idea about how to consider it with my C#2005 project than it will save my lots time.
When you connect to the database in your code, you'll a database connection string of some sort somewhere in there. Figure out the connection string for the Database server and set your code to point to that database server's connection info; I'd bet you currently you have it pointed at localhost
If you're using SQL Server you may need to enable remote connections on the database server.
added: you may need to modify firewall settings as well to allow SQL Server traffic (thanks Jared)
.
Edit: For putting the configuration string into a central location.
Your posted code
string connstr = "server=.;initial catalog=maa;uid=mah;pwd=mah";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
Change to
Assuming your application has a App.Config file then you'd add an entry in there like
<add key="DBConnectionString" value="server=.;initial catalog=maa;uid=mah;pwd=mah"/>
And change your C# code to be like
string connstr = ConfigurationManager.AppSettings["DBConnectionString"];
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
Putting the ConfigManager call into a class might be a good idea if you have a lot of settings to retrieve and/or believe the configuration storage methodology might change down the road. Going with the above example is WAY better than having the string literal scattered throughout your code.
Enable theTCP/IP connection in SQL Server. So that you can connect remotely from any pc within the network
check here
If your problem is that you embedded your connection string in the code, then you are going to have to do some refactoring. These would be the general steps, you will have to tailor them a bit to your situation.
Add your connection string to the app.config file.
Create a static/shared method that will read the connection string from the
config file.
Do a find and replace in your solution to replace all
of the hard coded connection strings in your code with the (class
and) name of the method that gets the connection string.
This is probably going to be easier than rewriting all of your data calls to use something like enterprise library or EF.
You will need to do as the others suggested, such as changing the connection string and enabling TCP/IP within SQL Server, but you will also likely need to configure your firewall to allow requests to SQL Server (default port of 1433) through.

Join tables from two databases in C#

With SQL Server I run this query with no problem...
SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'
I join two tables that reside in two different databases (mdb and mdb2).
But how can I do it in my .NET application?
When I need to use this statement
string cmdText = "SELECT SUM(Esi) AS Dispo
FROM [mdb].[dbo].[Query1] AS A
INNER JOIN [mdb2].[dbo].[TieCol] as B ON A.Alias=B.IDAlias
WHERE Alias LIKE 'SETUP%'";
this.OP = new SqlConnection(ConfigurationManager.ConnectionStrings["mdb2"].ConnectionString);
SqlCommand sqlCommand = new SqlCommand(cmdText, this.OP);
I can't execute it, since this.OP is the connection to mdb2... And for mdb?
How can I connect to both databases simultanously?
The SQL connection is to the server - the Initial catalog in a connection string behaves like use - it sets the default DB.
So your 3 part SQL query should work as is. So possibly
Make sure that the SQL login used by your app (or the account of your AppPool if using Web and Integrated Security) has the necessary access to both databases. (use RunAs on SQL Enterprise Manager as this account and try to run the query)
You might try escaping [Alias]
Also, if there is coupling between mdb1 and mdb2 (e.g. SPROCS in mdb1 use tables in mdb2 etc), for ease of maintenance, you might consider adding views in mdb1 for mdb2 objects. This allows for easy identification of cross-database dependencies. In this case, your query can use views which look like they are in the same database, although the underlying dependency on mdb2 is still there.
I'm not sure if there is a way to do this within the connection string. But you can probably do it using a four part reference to the table: [server].[database].[table].[column].
Your C# application only need to connect to one database server for this query.
Say your C# application connect to [mdb]. Database [mdb2] should b linked server in database [mdb].
Since you can run that query in sql server, so there must be one sql server connected to both databases. use that sql server in your C# connection string. That's it!

Connecting to a database from the beginning

I have been working in a business writing advanced software apps, and obviously im provided with access to our SQL server and all the connection strings needed.This is fine for my job now - but what if i wanted to do this for a new (very small) business... If i wanted to purchase a small database server and set up a piece of software that talks to the databases on this server, how would i go about a) Talking and connecting to the server in code (c#) and b)What would i need regarding things like internet/phone connections etc to make this possible.
Edit: the reason it would need a server is because it would need to be accessed from 2 or 3 different computers in different locations?
Actually there are quite a few ways to create a database connection, but I would say one of the easiest ways is to utilize the methods and classes found in System.Data.SQLClient. A basic connection would look something like the following:
using System.Data.SQLClient;
namespace YourNamespace
{
public class DatabaseConnect
{
public DataType getData()
{
DataType dataObj = new DataType();
SqlConnection testConn = new SqlConnection("connection string here");
SqlCommand testCommand = new SqlCommand("select * from dataTable", testConn);
testConn.Open()
using (SqlDataReader reader = testCommand.ExecuteReader())
{
while (reader.Read())
{
//Get data from reader and set into DataType object
}
}
return dataObj;
}
}
}
Keep in mind, this is a very, very simple version of a connection for reading data, but it should give you an idea of what you need to do. Make sure to use a "using" or "try/catch" statement to ensure that the connection is closed and resources are freed after each use (whether it successfully gets data or not).
As for your other question about what equipment you may require. In the beginning I would suggest just creating the database on your local machine and running tests from there. Once you are confident with trading data back and forth, feel free to move the database to another box or an online server. Any internet connection type should suffice, though I can't vouch for dial-up, haven't used it in years.
One final note, if you do happen to decide to move to an online server system, make sure that the service you use allows for outside connections. Certain services use shared server systems, and force users to use their internal database interfaces to manage and write to the database.
--- EDIT ---
As for the server system itself, build up a separate box on your local network that you can see, and load up the database software of your choice. Since you are using C#, it would probably be easiest to go with Microsoft SQL Server 2005 / 2008. The installation is rather straightforward, and it will prompt you to automatically create your first database while installing.
After installation it will be up to you to add in the tables, stored procedures, custom functions, etc... Once your base structure is created, go ahead and use the above code to make some simple connections. Since you are familiar with the above practices then I'm sure you know that all you really need to do is target the server machine and database in the connection string to be on your way.
In case your application is small (by small I mean the usage of resources like CPU and memory) then your SQL Server can reside on the same box.
Else you need to have a separate server box for your database and connect to that from your application. In this case, preferably your database box and application box would be on the local area network.
Check this link for having a connection to SQL Server from C# code - http://www.codeproject.com/KB/database/sql_in_csharp.aspx
cheers
You should probably expose your database with an xml web services layer, so that your architecture will be scalable. The general idea is host your sql server and webservices, using Native SQL Server XML Web Services you can make this available to your remote clients. When in your clients you simply add a service reference in Visual Studio and your data will now be available in your client app.
Hope this helps some.
Cheers
You may find the connectionstrings website useful - worth bookmarking.

concurrent SqlConnection and EntityConnection to a local Sql Express Server

I'm using Linq2Entity for most of my database operations. However for database creation, table creation and initial data insertion I use plain SQL files. Therefore I need both an SqlConnection and an EntityConnection. Unfortunately the Entity Framework starts complaining that the Sql Server is not listening on the other end of the pipe.
I'm not sure what the problem is here, it could be due to user instancing. Clearing the pool of the SqlConnection or disposing the connection instance does not help.
The connection string I'm using is the following:
"Data Source=.\SQLEXPRESS; Initial Catalog=dbname; Integrated Security=SSPI;"
update:
I have tried to use the EntityConnection for database maintenance purposes but I'm running into troubles. I can't use the EntityConnection to create databases and drop databases. The following syntax is unsupported for an EntityConnection but works fine for an SqlConnection to ms SQL express.
CREATE DATABASE silverfit ON ( NAME = silverfit, FILENAME = 'c:\silverfit\silverfit.mdf' );
Also for some reason the EntityConnection does not allow me to change databases which is necessary to drop a database. I'm afraid I still need the SqlConnection to create the database and tables..
Is there a way for SqlConnections and EntityConnections to coexist for local ms SQL express databases?
Thanks,
Wouter
Have you tried creating a SqlConnection which you then pass to the constructor for your EntityConnection? One of the overloads for EntityConnection takes a MetadataWorkspace and a DbConnection (from which SqlConnection derives.) The slight drawback of this is that you must create your MetadataWorkspace manually, which gathers up the .csdl, .ssdl, and .msl files that define your workspace. However, in the long run, you should be able to share a single connection for both executing DML queries, and using Entity Framework.
I don't agree that you need a plain SQL connection and Entity connection for this task, at least as you've described it. You can execute SQL using the Entity connection. Look at EntityConnection.CreateDbCommand. Naturally, there's a danger here that you are doing DB-server-specific things on a non-DB-server-specific instance like a EntityConnection. But it probably beats having a separate connection, in this case.
Did you try to use the EntityConnection.StoreConnection to retrieve the SqlConnection and execute commands with it ?
If you're trying attaching your database file to SQL Server Express at run time, which it seems as if you are, then only one connection can be open on it at once. This is a problem for other things, not just what you're trying to accomplish. Say, for instance, you connect to 'c:\silverfit\silverfit.mdf' through the server explorer in VS and try to open one of the tables in the db. After you open the table, try running your application. It will bomb.
However, if you open up SQL Management Studio Express (you can download it here), and then attach the database to the SQL Server, the problems you are experiencing should go away. At that point you should be able to open multiple connections to your database, via SQLConnection or EntityConnection.
Attaching your database at run time to the SQL Server express engine really only works well for demoing purposes, or proof of concepts.
Is ADO.NET holding a connection open to the database through connection pooling? Try adding Pooling=False to the connection string, as this may allow the database to be closed before you drop it.

Categories

Resources