Asp.net ajax update panel sharing a database connection - asp.net

I have a dropdown box and a literal tag inside an Update Panel. On the selection change event of the dropdown up requery the database and repopulate the literal tag and then call UPdatePanel.Update().
below, is there are way i can avoid having to create a new Oledbconnection each time as this seems slow. Can i reuse and store:
The Datasource
The connection in the page.
if so, how do i keep this state between calls from the GUI to the server? Here is my selection change code below
protected void cboPeople_SelectedIndexChanged(object sender, EventArgs e)
{
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
var objConn = new OleDbConnection(dataSource);
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}

With .NET is not a good idea to keep your connection alive longer than needs. Good practice would be to put a using statement around it (so it always gets cleaned up):
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
using(var objConn = new OleDbConnection(dataSource))
{
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}
.NET uses connection pooling, which means that when you close/dispose of the connection it doesn't actually close the connection, rather resets it and add it back to the pool. The next time a connection is needed it is used from the pool. So the overhead is not as much as you think and it is not slow. In actual fact you will find that it will use the same connection as long as only one at a time is needed.
The danger with keeping connections open is that they never get closed, and in high demand situations you run out of connections.

You need to recreate this for each request. You have a a state less server. you never know when or if your client will call back. You do not want to keep an open connection to the database nor could you simply service multiply clients while maintaining one database connection.
To deploy high-performance
applications, you must use connection
pooling. When you use the .NET
Framework Data Provider for OLE DB,
you do not have to enable connection
pooling because the provider manages
this automatically. For more
information about how to use
connection pooling with the .NET
Framework Data Provider for OLE DB,
see OLE DB, ODBC, and Oracle
Connection Pooling (ADO.NET).
From OleDbConnection Class

Related

Oracle connection pooling in ASP.net

I have an old intranet website written with vb.net and using Oracle.ManagedDataAccess mostly doing read operations from Oracle database 11g.
My db connection code is as follows.
Public Shared Function MyDBConnection(ByVal command_text As String, ByVal connstring As String, ByVal ParamArray parameters As OracleParameter()) As DataTable
Dim OraCommand As New OracleCommand
Dim tmp As New DataTable
Using ORAconnection = New OracleConnection(ConfigurationManager.ConnectionStrings(connstring).ConnectionString)
OraCommand.CommandText = command_text
If parameters IsNot Nothing AndAlso parameters.Length > 0 Then
For Each p In parameters
OraCommand.Parameters.Add(p.ParameterName, p.OracleDbType, p.Size).Value = p.Value
Next p
End If
OraCommand.Connection = ORAconnection
Try
ORAconnection.Open()
tmp.Load(OraCommand.ExecuteReader())
Catch ex As OracleException
End Try
End Using
Return tmp
End Function
And my oracle connection string is like this
<add name="ConnectionString" connectionString="User Id=userid;Password=userpadd;Data Source=servername:port/port_dp"/>
I was testing if my connections to the database were closing properly but it looks like connections on the database stayed open after being closed on my code. Eventually they close way after my query completed about 2 minutes, 10 minutes or hours later.
Is this connection pooling at work? or if there is something wrong with my code?
After reading about oracle pooling, it looks like the application should be reusing the same opened connection on the DB but in my case it looks like is opening new connections anyway.
So my question is, should I disable pooling on my connection string to make sure all connections open/close and not have connections lingering on the DB?
No, you should not disable connection pooling. In .NET connection pooling is managed by a mechanism outside of your reach, and you should proceed as if it is not there: open and close your connections as you normally would (i.e. at the beginning and end of every set of operations that you wish to enroll in a transaction/every set of ops that defines a good "unit of work" such as running a report, updating a table etc
The action of opening and closing connections in your code simply leases the from/returns them to the pool. .NET will manage the rest regarding maintaining a cache of some open connections to the db
Yes, there's pooling. The number of connection might have to do with the default value of min and max pool size. Also, OracleCommand does have a Dispose method that you are not calling.
Added: I see your empty catch statement, you don't need it when using "Using" (or ever). The Dispose will still be called if there's an exception.

Can you insert a new database connection in an existing database connection in OLEDB?

I am creating a program in which I am trying to have a new database connection in an existing database connection in OLEDB using ASP.net. Is that even possible?
"Connection within connection" is likely not what you have in mind. But there is no issue with having both OleDb and SQLServer connections operating together in one ASP.NET application, you can add these 2 or many more connections to one app.
Answer is yes. Please make sure you close the connections after using by using statement or close() explicitly. More here.
using (OleDbConnection connection1 = new OleDbConnection(connectionString1))
using (OleDbConnection connection2 = new OleDbConnection(connectionString2))
{
connection1.Open();
connection2.Open();
// Do something
}

multiple SqlConnections for one feature: bad idea?

I got an asp.net gridview connected to my sql database. When Inserting a new record or updating a record im doing some serverside checks and then either update/insert a record or do nothing. right now i got 2 methods CheckArtistExists and CheckSongExists which are both using a SqlConnection Object e.g.
public bool CheckSongExists(string _title, int _artistId)
{
int cnt = -1;
using (SqlConnection con = new SqlConnection(CS))
{
//check if song already is exists in DB
SqlCommand cmd = new SqlCommand("Select Count(ID) from tblSong WHERE Title = #newTitle AND ArtistId = #newArtistId;", con);
cmd.Parameters.AddWithValue(#"newTitle", _title);
cmd.Parameters.AddWithValue(#"newArtistId", _artistId);
con.Open();
cnt = (int)cmd.ExecuteScalar();
// if cnt ==1 song exists in DB, of cnt == 0 song doesnt exist
if(cnt == 1)
{ return true; }
else
{ return false; }
}
}
So for the Update function in the gridview i need to establish 3 SqlConnections (at max) one to check for the artist(if artist doesnt exist i have to insert a record to tblArtist first)
then a check if the song exists(only if artist exists) and finally if song doesnt exist I have to insert a new record.
I know database connections are valuable resources thats why i put them in a using block. So im not quite sure if its good style to use 3 SqlConnection objects to update/insert. Can you please tell me if my code is ok or if i should rather use another approach for this problem.
thank you
ADO.NET internally manages the underlying Connections to the DBMS in the ADO-NET Connection-Pool:
In practice, most applications use only one or a few different
configurations for connections. This means that during application
execution, many identical connections will be repeatedly opened and
closed. To minimize the cost of opening connections, ADO.NET uses an
optimization technique called connection pooling.
Connection pooling reduces the number of times that new connections
must be opened. The pooler maintains ownership of the physical
connection. It manages connections by keeping alive a set of active
connections for each given connection configuration. Whenever a user
calls Open on a connection, the pooler looks for an available
connection in the pool. If a pooled connection is available, it
returns it to the caller instead of opening a new connection. When the
application calls Close on the connection, the pooler returns it to
the pooled set of active connections instead of closing it. Once the
connection is returned to the pool, it is ready to be reused on the
next Open call.
So obviously there's no reason to avoid creating,opening or closing connections since actually they aren't created, opened and closed at all. This is "only" a flag for the connection pool to know when a connection can be reused or not. But it's a very important flag, because if a connection is "in use"(the connection pool assumes), a new physical connection must be openend to the DBMS what is very expensive.
So you're gaining no performance improvement if you "reuse" connections but the opposite.
Create, open(in case of Connections), use, close and dispose them where you need them(f.e. in a method)
use the using-statement to dispose and close(in case of Connections) implicitely
So yes, it's absolutely fine to use one connection per method since you are not using a physical connection at all if connection-pooling is enabled (default).
Another question is if you could improve your approach. You could create a stored-procedure which checks existence and updates or inserts accordingly.
Solutions for INSERT OR UPDATE on SQL Server

Constructing the Connection String for the DataContext Class

I see a couple of DataContext connection string questions. I'm going to try to differentiate this one a bit:
How does one construct a generic connection string to a database, localhost | User-PC\User | Some database... (it is hosted/managed by Microsoft SQL 2008)
I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time, and has to wait until each instance is disposed, in order for the data to be consistent for each user?
Is it possible, by any chance, to somehow enable LINQ in F#-Interactive, and connect to the database from there? I cannot figure out how to enable/load the System.Data dll into fsi. Maybe that is unique to my installation, or it is a common thread? (ie, my installation also does not recognize windows.base.dll--I have to manually get it from programs\reference assemblies).
Anyhow, I've pretty much conclusively discovered that
let x = new System.Data.Linq.DataContext("localhost")
...does not work.
1) How does one construct a generic connection string to a database?
There is no generic way to construct a connection string. The best thing to do is to keep the connection string in some configuration file where you can change it depending on your configuration (the name of SQL Server machine, authentication options, whether it is a file-based database or normal). There is a web site with examples for most of the options.
2) I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time [...]?
No, this is not how DataContext works. The DataContext does not keep a live connection to the server that would block anybody else from using the SQL server. It keeps some state (i.e. cached entities that were already obtained) and it uses optimistic concurrency to make sure that the state is consistent (you can use transactions to prevent other connections, if that's what you want).
3) Is it possible, by any chance, to somehow enable LINQ in F#-Interactive [...]?
That shouldn't be a problem. You can reference assemblies using #r "foo.dll" in F# interactive. The typical approach for F# 2.0 is to generate the data context using C# tools and then just reference it (for F# 3.0, things are easier because you can just use type provider).
If you generate LINQ to SQL data context for Northwind in C#, the F# Interactive use would look like this:
#r #"<whatever_path>\Northwind.dll"
#r "System.Data.Linq.dll"
open Northwind
open Microsoft.FSharp.Linq
let connStr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=<path>\NORTHWND.MDF;" +
#"Integrated Security=True;User Instance=True"
let operation () =
// Using 'use' to make sure it gets disposed at the end
use db = new NorthwindDataContext(connStr)
// do something with the database
There actually is a somewhat generic way to construct a connection string:
open System.Data.Common
open System.Data.SqlClient
let providerName = "System.Data.SqlClient"
let factory = DbProviderFactories.GetFactory(providerName)
let cnBuilder = factory.CreateConnectionStringBuilder() :?> SqlConnectionStringBuilder
cnBuilder.DataSource <- "localhost"
cnBuilder.InitialCatalog <- "MyDatabase"
cnBuilder.IntegratedSecurity <- true
let connStr = cnBuilder.ConnectionString
My approach was to have 1 connection string and then use that for all of my DataContext connections. So this code builds the EntityConnectionString based on MyConnString:
protected override MyEntities CreateObjectContext()
{
string ConnString =ConfigurationManager.ConnectionStrings["MyConnString"];
string seConn = ConfigurationManager.ConnectionStrings["MyEntities"].ToString();
EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder(seConn);
ecsb.ProviderConnectionString = ConnString;
EntityConnection ec = new EntityConnection(ecsb.ToString());
ScheduleEntities ctx = new ScheduleEntities(ec);
return ctx;
}

asp.net webservice OnUnload?

I'm creating a web service which has a number of methods, all of which make use of a SqlConnection. It seems logical that I would declare a class level connection and initialise it in the web service constructor.
Problem is I cannot find a definitive way to release the connection when the web service call completes, so I have a connection leak. I've tried overriding the Dipose() method but it doesn't get called in a reasonable timeframe (actually not at all in my testing). For good measure I also tried attaching a handler to the Disposed() event but as expected same problem.
Is there nothing similar to Page.OnUnload for web service classes? It seems hard to believe I would have to establish a separate connection in every individual method.
Any suggestions?
It seems logical that I would declare a class level connection and initialise it in the web service constructor.
No, this doesn't seem logical at all. ADO.NET uses a connection pooling so that you don't need to do this. This connection pool is per connection string per application domain.
So you could simply draw a new connection from the pool in each web method and return it to the pool at the end (the using statements will take care of this):
[WebMethod]
public void Foo()
{
// Here you are NOT creating a new connection to the database
// you are just drawing one from the connection pool
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
// Here you are NOT opening a new connection to the database
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something with the results
}
}
} // Here you are NOT closing the connection, you are just returning it to the pool
}
So here's an advice: don't try to manage connections manually by using some class fields, static fields, ... Leave this management to ADO.NET as it does it better.
Remark: The code I've shown usually resides in a data access layer which is called by the web method.

Resources