how to monitor SQL client connection number in C# - c#

In C# client side, we can open SQL connections based on connection string. Connection pool is used to improve the client performance.
We want to monitor how many connections are active and how many are free for use, which is very important to client side health check. Unfortunately, I didn't find any way to get this kind of information. Can any one tell me? Or I have to implement it by myself?

You need to have a wrapper class with count variable to monitor count of connection, on connection.Open() increment by 1 and on connetion.Close() decrement by 1.

public static DataTable GetActiveConnections()
{
DataTable objResult = new DataTable();
try
{
using (SqlConnection conection = new SqlConnection("ConnectionSetting"))
{
conection.Open();
using (SqlCommand cmd = new SqlCommand("sp_who", conection))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter adpter = new SqlDataAdapter())
{
adpter.SelectCommand = cmd;
adpter.Fill(objResult);
}
}
}
}
catch (Exception)
{
throw;
}
return objResult;
}
I haven't check it in c# application but i tested it in SQL Server Management Studio

Related

How to solve the "Connection Was Not Closed, The connections current state is open" in c#?

So I'm trying to practice c# and stumbled with the connection error, I already stated that my connection will be closed but it tells me that my connection is still open. I really have no idea what's wrong with this.
public void getdept()
{
con.Open();
string query = "SELECT * FROM positions where PositionName=" + cbxposname.SelectedValue.ToString() + "";
SqlCommand cmd = new SqlCommand(query, con);
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(query, con);
sda.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
txtdeptname.Text = dr["Department"].ToString();
}
con.Close();
}
Any tips is welcomed!
You appear to be using a common connection object. Don't. Create your connection object where you use. Do so with a using statement and then the connection will be closed and destroyed at the end of the block. Store your connection string in a common location and then use that each time to create a new connection, e.g.
var table = new DataTable();
using (var connection = new SqlConnection(connectionString)
using (var adapter = new SqlDataAdapter("SQL query here", connection)
{
adapter.Fill(table);
}
// use table here.
There are a number of things to note from this code, other than the using block.
Firstly, it doesn't explicitly open the connection because there's no point. The Fill and Update methods of a data adapter will implicitly open the connection if it's currently closed and it will implicitly close the connection if it opened it. When using a data adapter, the only reason to open the connection explicitly is if you're calling multiple Fill and/or Update methods, so the connection is closed and reopened in between. Even if you do open the connection though, there's still no need to close it explicitly because that happens implicitly at the end of the using block.
Secondly, this code doesn't create a command object because there's no point. In your original code, you create a command object and then you don't use it. If you already have a command object then you can pass that to the data adapter constructor but you don't do that. You pass the SQL query and the connection, so the data adapter will create its own SelectCommand.
In actual fact, there's no point even creating a connection object here. The data adapter has a constructor that accepts a SQL query and a connection string, so you can just create the data adapter and let it do the rest internally:
var table = new DataTable();
using (var adapter = new SqlDataAdapter("SQL query here", connectionString)
{
adapter.Fill(table);
}
// use table here.
You are unnecessary opening and closing connections in your case. It's not needed here.
Your code should look like this.
using (SqlConnection con = new SqlConnection(connetionString))
{
using (DataTable dt = new DataTable())
{
using (SqlDataAdapter sda = new SqlDataAdapter(sql, con))
{
sda.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
txtdeptname.Text = dr["Department"].ToString();
}
}
}
}
A few suggestions also, Please don't use * in the query, instead, use column names, Please use NOLOCK in the Query if it's required in your case and use the parameterized query.

C# DataTable and SqlDataAdapter open, close connection and performance issue

This is a function which I used to get data from database
public static DataTable getDataTable(string sql, string tableName)
{
DataTable dt = new DataTable();
try
{
SqlDataAdapter da = new SqlDataAdapter(sql, new SqlConnection(strConn));
da.Fill(dt);
dt.TableName = tableName;
}
catch (Exception)
{
dt = null;
}
return dt;
}
The questions are:
Does it open and close connection automatically? because it seems we only pass the sql query to SqlDataAdapter and it has no open or close the connection.
Does it will cause any performance to slow down the application?
Does it will cause any performance issue the server (Memory)?
Thanks in advance.
i hope this help you
Answer 1 :
If I remember correctly the SQLConnection manages connection pooling behind the scenes.
Here is a nice article about this very subject:
https://msdn.microsoft.com/en-us/library/ms971481.aspx
Also, a best practice is to use the "using" keyword to wrap your connection because it will automatically close your connection once the scope exits (with or without an exception)
using(SqlConnection conn = new SqlConnection())
{
conn.Open();
//Do Work with connection
} //Connection automatically closes here without the need to call conn.Close()
Answer 2:
Sql Connection open slow down or make application performance better
Answer 3 :
What is Best Approach for Opening/Closing SqlConnection in C#

Check online connection with SQL server, switch to offline C# Windows Application

I have a C# Windows app that I am creating with connection to a MS SQL server. I need the ability to switch to a local instance of SQL Server express if connectivity is down. This app is in a remote area where online is hit and miss. When connectivity goes down, I need the connection strings to reflect to the local server. I have logic to resync items from the local db to the live one once connection is restored. However, I am having issues trying to test connectivity automatically. The connection string in my app.config has both live and offline connections with the following code:
SqlConnection con = new SqlConnection(Properties.Settings.Default.MyLiveConnectionString);
If connection goes down, I want the local connection to use:
SqlConnection con = new SqlConnection(Properties.Settings.Default.MyLocalConnectionString);
Does anyone have a suggestion on how to make this happen seamlessly and quick?
I can test connections using try/catch, but it takes several seconds to time out before continuing.
public void Connect()
{
string connectionStr = string.Empty;
try
{
if(CheckConnection(Properties.Settings.Default.MyLiveConnectionString))
connectionStr = Properties.Settings.Default.MyLiveConnectionString;
}
catch (Exception ex)
{
//Log this, etc...
}
if (string.IsNullOrWhiteSpace(connectionStr))
connectionStr = Properties.Settings.Default.MyLocalConnectionString;
using (SqlConnection conn = new SqlConnection(connectionStr))
{
}
}
private static bool CheckConnection(string connectionString)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("SELECT 1", conn);
conn.Open();
if ((int)cmd.ExecuteScalar() == 1)
return true;
}
return false;
}

Foreach and SqlConnection Using Statement

I'm trying to figure out which is more efficient to run. I have a foreach of tables and I'm wondering if it should be outside of my using or inside of it. Examples below.
the using (SqlConnection) inside of the foreach:
foreach (string tableName in desiredTables)
{
using (SqlConnection connection = new SqlConnection(cloudConnectionString))
{
connection.Open();
string query = string.Format("SELECT id, active, createdon, modifiedon FROM {0}", tableName);
using (SqlCommand cmd = connection.CreateCommand())
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
SqlDataAdapter dAdapter = new SqlDataAdapter(cmd);
try
{
dAdapter.Fill(dSet, tableName);
}
catch
{
throw;
}
}
}
}
Versus the foreach inside of the using (SqlConnection):
using (SqlConnection connection = new SqlConnection(cloudConnectionString))
{
connection.Open();
foreach (string tableName in desiredTables)
{
string query = string.Format("SELECT id, active, createdon, modifiedon FROM {0}", tableName);
using (SqlCommand cmd = connection.CreateCommand())
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
SqlDataAdapter dAdapter = new SqlDataAdapter(cmd);
try
{
dAdapter.Fill(dSet, tableName);
}
catch
{
throw;
}
}
}
}
I'm trying to optimize this for a faster pull from the DB and I'm not sure which way is recommended/better. Advice would be great.
You'll have to try it and measure it to be certain, but I doubt you'll see a huge difference either way. Connections are pooled by .NET, so creating them in a loop (I'm assuming you just have a handful of tables, not several hundred) should not be a significant bottleneck. You'll likely spend a LOT more time in network I/O and actually populating the DataSet (which does have a lot of overhead).
Bottom line - fine one way that works (so you have something to revert back to) and try it multiple ways and see if one method makes a significant difference to the application overall.
Generally, Open and Close a database connection multiple times in a network environment can be expensive (connection data travels thru your network several rounds, the C# CLR has to allocate and free resource several times, the Garbage Collection has more works to do later...), so you should try to reuse your database connection by putting it outside the loop.

When using an OracleCommand in .net must the OracleClient be installed on the machine or does .net cover this?

I want to make a simple query on an Oracle database from .net using similar code to this.
using System;
using System.Data;
using Oracle.DataAccess.Client;
class Sample
{
static void Main()
{
// Connect to Oracle
string constr = "User Id=scott;Password=tiger;Data Source=AKI1.WORLD";
OracleConnection con = new OracleConnection(constr);
con.Open();
// Display Version Number
Console.WriteLine("Connected to Oracle " + con.ServerVersion);
// Read REF CURSOR into DataSet
DataSet ds = new DataSet();
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "GetComplexTabPkg.GetEmp";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("p_dep", OracleDbType.Int16).Value = 20;
cmd.Parameters.Add("p_ref", OracleDbType.RefCursor).Direction
= ParameterDirection.Output;
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.TableMappings.Add("Emp", "Emp");
da.Fill(ds);
// Close and Dispose OracleConnection
con.Close();
con.Dispose();
// Show Message
Console.WriteLine("DataSet filled");
}
}
My only concern is does the Oracle Client need to be installed on the web server that is running this code? It's my first time using this and I would like to avoid any obvious issues that can be prevented. Thanks.
Yes, Oracle Client need to be installed in web server. The work around will be to ship your application with Instant Oracle Client
On my Own I just install 64-bit Oracle Data Access Components (ODAC) Downloads, which seems to be lighter than Oracle Client.

Categories