Wrox Home  
Search P2P Archive for: Go

  Return to Index  

aspx thread: SQLConnection speed vs. ADODB.Connection


Message #1 by "Anders Lundholm" <lundholm@s...> on Mon, 27 Nov 2000 17:03:06 +0100
Hello people!



I am eager to see just how fast the SQL Server specific namespace is in 

the .NET framework when compared to the older ADODB COM components. Thus 

I decided to write a simple performance test where ASPx and ASP was 

supposed to compete.



Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0



This is a long letter but I think it covers some questions a lot of 

current and prospective db-programmers ask: Which is faster, when and 

why - and how can I take advantage of each?!



I have a question in the bottom of this mail, so please take your time 

to read this throroughly and try to answer my question if possible!



-- =3D --



Test #1:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Close db-connection

d. Loop next

e. Calculate time



Result:

ASP+: 8.0 secs.

ASP: 0.64 secs.



Comments on test #1:

This is very strange. I know ASP is really good at communicating with 

the ODBC layer, but this is scarry. The only answer I can come up with 

is, the ASP Connection object isn't opening a 'real' connection to the 

SQL Server - just a 'proxy' of that connection. Once the first data 

starts to flow to/from through that proxy, ASP will ask for a 'real' 

connection.



The other answer is, that the .NET framework haven't incorporated proper 

connection-pooling for the SQL Server namespace yet (which I really hope 

- look at those numbers!). Thus, the ASPx example opens a 'real' 

database-connection to the SQL Server, which naturally is heavier (the 

below test kinda supports that theory).



No-one would - under all circumstances - open/close a connection without 

doing anything with it first! Only me, I guess! :)



-- =3D --



Test #2:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Close db-connection

g. Loop next

h. Calculate time



Result:

ASP+: 18.0 secs.

ASP: 18 secs.



Comments on test #2:

It clearly shows that the SQLDataReader is outperforming the ADODB 

Records by atleast 50%. Nice, but not as fast as one would want - we're 

talking SQL Server optimized code here .. come on! ASP is clearly 

getting a lot slower when it's going to do something with that 

connection, instead of just using the 'proxy' (or whatever).



-- =3D --



Test #3:



Please notice that I've left the opening/closing of the db-connection 

outside of the loop - just to see the difference. You'll like the 

outcome:



Pseudocode:

a. Open db-connection to SQL Server

b. Do a loop with 1000 iterations

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Loop next

g. Close db-connection

h. Calculate time



Result:

ASP+: 4.0 secs.

ASP: 16 secs.



Comments on test #3:

The SQL Server namespace is obviously gaining a lot of performance once 

it got rid of the open/close connection code in each iteration. But, how 

come it's really that slow on it? I'd expected the SQL Server namespace 

to perform just as fast as the ASP, using the proxy method and only take 

a performance-hit once data starts to flow.



Question (and discussion):

When programming datalayer-components using the .NET framework and the 

specific SQL Server optimized namespace, it would come with a big 

performance-penalty if you were to open a db-connection in each and 

every function of your datalayer.



Unlike regular ASP - you can't (in ASPx) declare a set of global 

variables for your page (e.g. oConn =3D valid database-connection) 

because everything actually is a self-contained assembly. Thus, 

variables have assembly level scope.



Compared to regular ASP, I can't use the global variable holding the 

connection for the entire page (e. g. oConn) and use that very 

connection in an include-file or pagelet. I'll have to create my own 

connection in each and every part of the assembly.



As the above test shows, then you're actually making your application 

'N' times slower for each function you're calling in the code (provided 

those functions need database-connections), because each function would 

need a database-connection. The same goes for ASP, but you can still 

rely on the 'global' connection-variable. So, what do we do? We need to 

eliminate the overhead and look at a solution.



Theory:

I've given this a lot of thought and the only solution would be to make 

a 'rule', which says that the calling function should always provide a 

valid database-connection to the data-layer when it requests data. This 

would ensure multi-use of the same db-connection (when it's passed as an 

function-argument like the following):



(C#):

// Master function always providing a 'global' connection as 

function-argument

public void Master() {

    SQLConnection oConn =3D new SQLConnection

    // More oConn code here gives a valid connection

    string strPage =3D GetPages(oConn, 20, 10);

    string strColumn =3D GetColumns(oConn, 20);

}



public void GetPages(SQLConnection oConn, int intPageId, int 

intRowCount) {

    // Use oConn as provided connection and remember to check for 

validity

}



public void GetColumns(SQLConnection oConn, int intNumCols) {

    // Use oConn as provided connection and remember to check for 

validity

}



It just seems really *weird* to always pass a db-connection as a 

argument when you've been used to having global variables available. I 

know, globals are bad, but for db-connections they're really nice.



I really hope you'll willing to join the discussion. We must adhere to 

the best solution at all times - which is why I'm asking this before 

starting to do the work here.



Thanks in advance!



With Regards

Anders Lundholm - lundholm@s...

--







Message #2 by Scott Davis <Scott.D@e...> on Mon, 27 Nov 2000 15:54:25 -0500
Your conclusion is correct.  We've been working on a rather large project 

here using ASP.NET and C# for the past 3 months.  This is exactly what we 

are doing.  You ALWAYS want to limit the amount of times that you are 

opening and closing a connection to a database, as your tests show, it is 

rather expensive.  All of our data-layer components either take a 

SQLConnection object as a parameter in the constructor or have methods 

that take a SQLConnection as a parameter.



You really have to make a paradigm shift towards true object-oriented 

programming to take advantage of what ASP.NET has to offer over ASP.



-----Original Message-----

From: Anders Lundholm [mailto:lundholm@s...]

Sent: Monday, November 27, 2000 11:03 AM

To: ASP+

Subject: [aspx] SQLConnection speed vs. ADODB.Connection





Hello people!



I am eager to see just how fast the SQL Server specific namespace is in 

the .NET framework when compared to the older ADODB COM components. Thus I 

decided to write a simple performance test where ASPx and ASP was supposed 

to compete.



Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0



This is a long letter but I think it covers some questions a lot of 

current and prospective db-programmers ask: Which is faster, when and why - and how can I take advantage of each?!





I have a question in the bottom of this mail, so please take your time to 

read this throroughly and try to answer my question if possible!



-- = --



Test #1:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Close db-connection

d. Loop next

e. Calculate time



Result:

ASP+: 8.0 secs.

ASP: 0.64 secs.



Comments on test #1:

This is very strange. I know ASP is really good at communicating with the 

ODBC layer, but this is scarry. The only answer I can come up with is, the 

ASP Connection object isn't opening a 'real' connection to the SQL Server -

 just a 'proxy' of that connection. Once the first data starts to flow 

to/from through that proxy, ASP will ask for a 'real' connection.



The other answer is, that the .NET framework haven't incorporated proper 

connection-pooling for the SQL Server namespace yet (which I really hope - 

look at those numbers!). Thus, the ASPx example opens a 'real' database-

connection to the SQL Server, which naturally is heavier (the below test 

kinda supports that theory).



No-one would - under all circumstances - open/close a connection without 

doing anything with it first! Only me, I guess! :)



-- = --



Test #2:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Close db-connection

g. Loop next

h. Calculate time



Result:

ASP+: 18.0 secs.

ASP: 18 secs.



Comments on test #2:

It clearly shows that the SQLDataReader is outperforming the ADODB Records 

by atleast 50%. Nice, but not as fast as one would want - we're talking 

SQL Server optimized code here .. come on! ASP is clearly getting a lot 

slower when it's going to do something with that connection, instead of 

just using the 'proxy' (or whatever).



-- = --



Test #3:



Please notice that I've left the opening/closing of the db-connection 

outside of the loop - just to see the difference. You'll like the outcome:



Pseudocode:

a. Open db-connection to SQL Server

b. Do a loop with 1000 iterations

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Loop next

g. Close db-connection

h. Calculate time



Result:

ASP+: 4.0 secs.

ASP: 16 secs.



Comments on test #3:

The SQL Server namespace is obviously gaining a lot of performance once it 

got rid of the open/close connection code in each iteration. But, how come 

it's really that slow on it? I'd expected the SQL Server namespace to 

perform just as fast as the ASP, using the proxy method and only take a 

performance-hit once data starts to flow.



Question (and discussion):

When programming datalayer-components using the .NET framework and the 

specific SQL Server optimized namespace, it would come with a big 

performance-penalty if you were to open a db-connection in each and every 

function of your datalayer.



Unlike regular ASP - you can't (in ASPx) declare a set of global variables 

for your page (e.g. oConn = valid database-connection) because everything 

actually is a self-contained assembly. Thus, variables have assembly level 

scope.



Compared to regular ASP, I can't use the global variable holding the 

connection for the entire page (e. g. oConn) and use that very connection 

in an include-file or pagelet. I'll have to create my own connection in 

each and every part of the assembly.



As the above test shows, then you're actually making your application 'N' 

times slower for each function you're calling in the code (provided those 

functions need database-connections), because each function would need a 

database-connection. The same goes for ASP, but you can still rely on 

the 'global' connection-variable. So, what do we do? We need to eliminate 

the overhead and look at a solution.



Theory:

I've given this a lot of thought and the only solution would be to make 

a 'rule', which says that the calling function should always provide a 

valid database-connection to the data-layer when it requests data. This 

would ensure multi-use of the same db-connection (when it's passed as an 

function-argument like the following):



(C#):

// Master function always providing a 'global' connection as function-argument

public void Master() {

    SQLConnection oConn = new SQLConnection

    // More oConn code here gives a valid connection

    string strPage = GetPages(oConn, 20, 10);

    string strColumn = GetColumns(oConn, 20);

}



public void GetPages(SQLConnection oConn, int intPageId, int intRowCount) {

    // Use oConn as provided connection and remember to check for validity

}



public void GetColumns(SQLConnection oConn, int intNumCols) {

    // Use oConn as provided connection and remember to check for validity

}



It just seems really *weird* to always pass a db-connection as a argument 

when you've been used to having global variables available. I know, 

globals are bad, but for db-connections they're really nice.



I really hope you'll willing to join the discussion. We must adhere to the 

best solution at all times - which is why I'm asking this before starting 

to do the work here. 



Thanks in advance!



With Regards

Anders Lundholm - lundholm@s...

--









Message #3 by "Fredrik Normen" <fredrik.normen@e...> on Tue, 28 Nov 2000 09:23:10 -0000
> Your conclusion is correct.  We've been working on a rather large project

> here using ASP.NET and C# for the past 3 months.  This is exactly what we

> are doing.  You ALWAYS want to limit the amount of times that you are 

> opening and closing a connection to a database, as your tests show, it is

> rather expensive.  All of our data-layer components either take a 

> SQLConnection object as a parameter in the constructor or have methods 

> that take a SQLConnection as a parameter.



You mean you pass a SQLConnection from the business layer ?

If so you will have a data dependency in the business layer and it's not

very nice. The business layer should not know where the data comes from.

And even if you do so, the connection must be maid somewhere else and what

we have seen is that ADO handles connections much faster then ADO.NET.



A connection in ADO.Net must be faster than a connection in ADO, or

Microsoft will have problems with this, because if you have 100 users at

the same time they will each do a connection with ADO.NET, and if we look

at the test this is very time consuming. To increase scalability and

performance in ASP.NET the ADO.NET must be much faster, even if we think

in terms of OO.



I will never tolerate this bad result, in the final release of ADO.Net I

wan't to see big changes, I want to se that ADO.NET is much faster than

ADO or Microsoft have failed with ADO.NET.



/Fredrik Normén









> 

> -----Original Message-----

> From: Anders Lundholm [mailto:lundholm@s...]

> Sent: Monday, November 27, 2000 11:03 AM

> To: ASP+

> Subject: [aspx] SQLConnection speed vs. ADODB.Connection

> 

> 

> Hello people!

> 

> I am eager to see just how fast the SQL Server specific namespace is in

> the .NET framework when compared to the older ADODB COM components. Thus I

> decided to write a simple performance test where ASPx and ASP was supposed

> to compete.

> 

> Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0

> 

> This is a long letter but I think it covers some questions a lot of 

> current and prospective db-programmers ask: Which is faster, when and why - and how can I take advantage of each?!

> 

> 

> I have a question in the bottom of this mail, so please take your time to

> read this throroughly and try to answer my question if possible!

> 

> -- = --

> 

> Test #1:

> Pseudocode:

> a. Do a loop with 1000 iterations

> b. Open db-connection to SQL Server

> c. Close db-connection

> d. Loop next

> e. Calculate time

> 

> Result:

> ASP+: 8.0 secs.

> ASP: 0.64 secs.

> 

> Comments on test #1:

> This is very strange. I know ASP is really good at communicating with the

> ODBC layer, but this is scarry. The only answer I can come up with is, the

> ASP Connection object isn't opening a 'real' connection to the SQL Server -

>  just a 'proxy' of that connection. Once the first data starts to flow 

> to/from through that proxy, ASP will ask for a 'real' connection.

> 

> The other answer is, that the .NET framework haven't incorporated proper

> connection-pooling for the SQL Server namespace yet (which I really hope -

> look at those numbers!). Thus, the ASPx example opens a 'real' database-

> connection to the SQL Server, which naturally is heavier (the below test

> kinda supports that theory).

> 

> No-one would - under all circumstances - open/close a connection without

> doing anything with it first! Only me, I guess! :)

> 

> -- = --

> 

> Test #2:

> Pseudocode:

> a. Do a loop with 1000 iterations

> b. Open db-connection to SQL Server

> c. Create a recordset and perform a simple select.

> d. Loop through all records in each recordset (no display)

> e. Close current recordset

> f. Close db-connection

> g. Loop next

> h. Calculate time

> 

> Result:

> ASP+: 18.0 secs.

> ASP: 18 secs.

> 

> Comments on test #2:

> It clearly shows that the SQLDataReader is outperforming the ADODB Records

> by atleast 50%. Nice, but not as fast as one would want - we're talking

> SQL Server optimized code here .. come on! ASP is clearly getting a lot

> slower when it's going to do something with that connection, instead of

> just using the 'proxy' (or whatever).

> 

> -- = --

> 

> Test #3:

> 

> Please notice that I've left the opening/closing of the db-connection 

> outside of the loop - just to see the difference. You'll like the outcome:

> 

> Pseudocode:

> a. Open db-connection to SQL Server

> b. Do a loop with 1000 iterations

> c. Create a recordset and perform a simple select.

> d. Loop through all records in each recordset (no display)

> e. Close current recordset

> f. Loop next

> g. Close db-connection

> h. Calculate time

> 

> Result:

> ASP+: 4.0 secs.

> ASP: 16 secs.

> 

> Comments on test #3:

> The SQL Server namespace is obviously gaining a lot of performance once it

> got rid of the open/close connection code in each iteration. But, how come

> it's really that slow on it? I'd expected the SQL Server namespace to 

> perform just as fast as the ASP, using the proxy method and only take a

> performance-hit once data starts to flow.

> 

> Question (and discussion):

> When programming datalayer-components using the .NET framework and the 

> specific SQL Server optimized namespace, it would come with a big 

> performance-penalty if you were to open a db-connection in each and every

> function of your datalayer.

> 

> Unlike regular ASP - you can't (in ASPx) declare a set of global variables

> for your page (e.g. oConn = valid database-connection) because everything

> actually is a self-contained assembly. Thus, variables have assembly level

> scope.

> 

> Compared to regular ASP, I can't use the global variable holding the 

> connection for the entire page (e. g. oConn) and use that very connection

> in an include-file or pagelet. I'll have to create my own connection in

> each and every part of the assembly.

> 

> As the above test shows, then you're actually making your application 'N'

> times slower for each function you're calling in the code (provided those

> functions need database-connections), because each function would need a

> database-connection. The same goes for ASP, but you can still rely on 

> the 'global' connection-variable. So, what do we do? We need to eliminate

> the overhead and look at a solution.

> 

> Theory:

> I've given this a lot of thought and the only solution would be to make

> a 'rule', which says that the calling function should always provide a 

> valid database-connection to the data-layer when it requests data. This

> would ensure multi-use of the same db-connection (when it's passed as an

> function-argument like the following):

> 

> (C#):

> // Master function always providing a 'global' connection as function-argument

> public void Master() {

>     SQLConnection oConn = new SQLConnection

>     // More oConn code here gives a valid connection

>     string strPage = GetPages(oConn, 20, 10);

>     string strColumn = GetColumns(oConn, 20);

> }

> 

> public void GetPages(SQLConnection oConn, int intPageId, int intRowCount) {

>     // Use oConn as provided connection and remember to check for validity

> }

> 

> public void GetColumns(SQLConnection oConn, int intNumCols) {

>     // Use oConn as provided connection and remember to check for validity

> }

> 

> It just seems really *weird* to always pass a db-connection as a argument

> when you've been used to having global variables available. I know, 

> globals are bad, but for db-connections they're really nice.

> 

> I really hope you'll willing to join the discussion. We must adhere to the

> best solution at all times - which is why I'm asking this before starting

> to do the work here. 

> 

> Thanks in advance!

> 

> With Regards

> Anders Lundholm - lundholm@s...

> --

Message #4 by =?iso-8859-1?Q?Fredrik_Norm=E9n?= <fredrik.normen@e...> on Tue, 28 Nov 2000 09:46:02 +0100
Hi,



Hmm this is strange, I have done a simular test on my computer:



PIII 500 Mhz 196 Mb Ram, Win2k Server/SQL Server 2000.



TEst #1

1. Open a connection  ( Northwind DB )

2. Select all customers

3. Do a loop and display each customer

4. close the connection



ASP.NET:

I use SQLConnection, SQLCommand and SQLDataReader



ASP v 3.0:

I use ADO 2.6 with SQLOLEDB provider, Connection object, Recordset



Result:

ASP.NET	0,01 s

ASP		0,01 s



This is very strange.



Test #2

1. Do a loop with 0-1000

1. Open a connection  ( Northwind DB )

2. Select all customers

4. close the connection

5. Next



ASP.NET	10.6 s

ASP		2.2



I don't believe this, ASP v 3,0 with ADO 2.6 and SQLOLEDB provider is much

faster than

ASP.NET with SQLCommand.

NOTE: This is only a test, I will never use this in a real application, but

it's fun to compare how long it takes for a connection to be open with ASP

vs ASP.NET.



Maybe this result will be change when we leave the beta stage of VS.nET.

All the test here is done with Beta 1 of .NET so I think we should wait and

see if there is any changes when beta 2 and 3 is released.



/Frerik Normen







-----Original Message-----



From: Anders Lundholm [mailto:lundholm@s...]

Sent: den 27 november 2000 17:03

To: ASP+

Subject: [aspx] SQLConnection speed vs. ADODB.Connection





Hello people!



I am eager to see just how fast the SQL Server specific namespace is in the

.NET framework when compared to the older ADODB COM components. Thus I

decided to write a simple performance test where ASPx and ASP was supposed

to compete.



Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0



This is a long letter but I think it covers some questions a lot of current

and prospective db-programmers ask: Which is faster, when and why - and how

can I take advantage of each?!



I have a question in the bottom of this mail, so please take your time to

read this throroughly and try to answer my question if possible!



-- = --



Test #1:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Close db-connection

d. Loop next

e. Calculate time



Result:

ASP+: 8.0 secs.

ASP: 0.64 secs.



Comments on test #1:

This is very strange. I know ASP is really good at communicating with the

ODBC layer, but this is scarry. The only answer I can come up with is, the

ASP Connection object isn't opening a 'real' connection to the SQL Server -

just a 'proxy' of that connection. Once the first data starts to flow

to/from through that proxy, ASP will ask for a 'real' connection.



The other answer is, that the .NET framework haven't incorporated proper

connection-pooling for the SQL Server namespace yet (which I really hope -

look at those numbers!). Thus, the ASPx example opens a 'real'

database-connection to the SQL Server, which naturally is heavier (the below

test kinda supports that theory).



No-one would - under all circumstances - open/close a connection without

doing anything with it first! Only me, I guess! :)



-- = --



Test #2:

Pseudocode:

a. Do a loop with 1000 iterations

b. Open db-connection to SQL Server

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Close db-connection

g. Loop next

h. Calculate time



Result:

ASP+: 18.0 secs.

ASP: 18 secs.



Comments on test #2:

It clearly shows that the SQLDataReader is outperforming the ADODB Records

by atleast 50%. Nice, but not as fast as one would want - we're talking SQL

Server optimized code here .. come on! ASP is clearly getting a lot slower

when it's going to do something with that connection, instead of just using

the 'proxy' (or whatever).



-- = --



Test #3:



Please notice that I've left the opening/closing of the db-connection

outside of the loop - just to see the difference. You'll like the outcome:



Pseudocode:

a. Open db-connection to SQL Server

b. Do a loop with 1000 iterations

c. Create a recordset and perform a simple select.

d. Loop through all records in each recordset (no display)

e. Close current recordset

f. Loop next

g. Close db-connection

h. Calculate time



Result:

ASP+: 4.0 secs.

ASP: 16 secs.



Comments on test #3:

The SQL Server namespace is obviously gaining a lot of performance once it

got rid of the open/close connection code in each iteration. But, how come

it's really that slow on it? I'd expected the SQL Server namespace to

perform just as fast as the ASP, using the proxy method and only take a

performance-hit once data starts to flow.



Question (and discussion):

When programming datalayer-components using the .NET framework and the

specific SQL Server optimized namespace, it would come with a big

performance-penalty if you were to open a db-connection in each and every

function of your datalayer.



Unlike regular ASP - you can't (in ASPx) declare a set of global variables

for your page (e.g. oConn = valid database-connection) because everything

actually is a self-contained assembly. Thus, variables have assembly level

scope.



Compared to regular ASP, I can't use the global variable holding the

connection for the entire page (e. g. oConn) and use that very connection in

an include-file or pagelet. I'll have to create my own connection in each

and every part of the assembly.



As the above test shows, then you're actually making your application 'N'

times slower for each function you're calling in the code (provided those

functions need database-connections), because each function would need a

database-connection. The same goes for ASP, but you can still rely on the

'global' connection-variable. So, what do we do? We need to eliminate the

overhead and look at a solution.



Theory:

I've given this a lot of thought and the only solution would be to make a

'rule', which says that the calling function should always provide a valid

database-connection to the data-layer when it requests data. This would

ensure multi-use of the same db-connection (when it's passed as an

function-argument like the following):



(C#):

// Master function always providing a 'global' connection as

function-argument

public void Master() {

    SQLConnection oConn = new SQLConnection

    // More oConn code here gives a valid connection

    string strPage = GetPages(oConn, 20, 10);

    string strColumn = GetColumns(oConn, 20);

}



public void GetPages(SQLConnection oConn, int intPageId, int intRowCount) {

    // Use oConn as provided connection and remember to check for validity

}



public void GetColumns(SQLConnection oConn, int intNumCols) {

    // Use oConn as provided connection and remember to check for validity

}



It just seems really *weird* to always pass a db-connection as a argument

when you've been used to having global variables available. I know, globals

are bad, but for db-connections they're really nice.



I really hope you'll willing to join the discussion. We must adhere to the

best solution at all times - which is why I'm asking this before starting to

do the work here.



Thanks in advance!



With Regards

Anders Lundholm - lundholm@s...

--



Message #5 by Scott Davis <Scott.D@e...> on Tue, 28 Nov 2000 08:22:25 -0500
Frederik, there is one simple reason to pass around a SQLConnection or 

ADOConnection.  Performance.  Our data-layer is organized into objects. 

 Those objects are usually persisted to a database table.  So, the 

problem with not passing around the opened Connection object, is that I 

would have to open a new connection in each of my data-layer objects.  

If one of my business layer methods, needs to access two or more of my 

data-layer objects, then I have to open a connection 2 or more times.  

If I create one Connection object and pass it in to the data-layer 

objects, I only have to have one Connection object and I only have to 

open it one time.



I somewhat agree with your assessment that the business layer has a 

data dependency, but not so much as you are making it out.  You 

business layer MUST have a data dependency, otherwise, what good is it? 

 If I use the ADOConnection object in the business layer, I'm still 

sheltered from any changes in the data-layer as to the provider of my 

data.  The business layer won't care where the data comes from.  Our 

business layer access it's data from Collections in the data-layer 

objects.  That part will never change, regardlesss of where the data is 

coming from.  If you change providers or servers or whatever, you 

simply change your Connection String(s) in one central place...real 

simple.



Any downside to creating and opening the connection objects in my 

business layer is far less than the downside and the performance loss 

that I will incur by creating and opening multiple Connection objects.



Scott Davis

MCSD, MCP

International Parts

Decision Consultants Inc.





-----Original Message-----

From: Fredrik Normen [mailto:fredrik.normen@e...]

Sent: Tuesday, November 28, 2000 4:23 AM

To: ASP+

Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection





> Your conclusion is correct.  We've been working on a rather large 

project

> here using ASP.NET and C# for the past 3 months.  This is exactly 

what we

> are doing.  You ALWAYS want to limit the amount of times that you are 



> opening and closing a connection to a database, as your tests show, 

it is

> rather expensive.  All of our data-layer components either take a

> SQLConnection object as a parameter in the constructor or have 

methods

> that take a SQLConnection as a parameter.





You mean you pass a SQLConnection from the business layer ?

If so you will have a data dependency in the business layer and it's 

not

very nice. The business layer should not know where the data comes 

from.

And even if you do so, the connection must be maid somewhere else and 

what

we have seen is that ADO handles connections much faster then ADO.NET.



A connection in ADO.Net must be faster than a connection in ADO, or

Microsoft will have problems with this, because if you have 100 users 

at

the same time they will each do a connection with ADO.NET, and if we 

look

at the test this is very time consuming. To increase scalability and

performance in ASP.NET the ADO.NET must be much faster, even if we 

think

in terms of OO.



I will never tolerate this bad result, in the final release of ADO.Net 

I

wan't to see big changes, I want to se that ADO.NET is much faster than

ADO or Microsoft have failed with ADO.NET.



/Fredrik Norm=E9n









>

> -----Original Message-----

> From: Anders Lundholm [mailto:lundholm@s...]

> Sent: Monday, November 27, 2000 11:03 AM

> To: ASP+

> Subject: [aspx] SQLConnection speed vs. ADODB.Connection

>

>

> Hello people!

>

> I am eager to see just how fast the SQL Server specific namespace is 

in

> the .NET framework when compared to the older ADODB COM components. 

Thus I

> decided to write a simple performance test where ASPx and ASP was 

supposed

> to compete.

>

> Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0

>

> This is a long letter but I think it covers some questions a lot of

> current and prospective db-programmers ask: Which is faster, when and 

why - and how can I take advantage of each?!

>

>

> I have a question in the bottom of this mail, so please take your 

time to

> read this throroughly and try to answer my question if possible!

>

> -- =3D --

>

> Test #1:

> Pseudocode:

> a. Do a loop with 1000 iterations

> b. Open db-connection to SQL Server

> c. Close db-connection

> d. Loop next

> e. Calculate time

>

> Result:

> ASP+: 8.0 secs.

> ASP: 0.64 secs.

>

> Comments on test #1:

> This is very strange. I know ASP is really good at communicating with 

the

> ODBC layer, but this is scarry. The only answer I can come up with 

is, the

> ASP Connection object isn't opening a 'real' connection to the SQL 

Server -

>  just a 'proxy' of that connection. Once the first data starts to 

flow

> to/from through that proxy, ASP will ask for a 'real' connection.

>

> The other answer is, that the .NET framework haven't incorporated 

proper

> connection-pooling for the SQL Server namespace yet (which I really 

hope -

> look at those numbers!). Thus, the ASPx example opens a 'real' 

database-

> connection to the SQL Server, which naturally is heavier (the below 

test

> kinda supports that theory).

>

> No-one would - under all circumstances - open/close a connection 

without

> doing anything with it first! Only me, I guess! :)

>

> -- =3D --

>

> Test #2:

> Pseudocode:

> a. Do a loop with 1000 iterations

> b. Open db-connection to SQL Server

> c. Create a recordset and perform a simple select.

> d. Loop through all records in each recordset (no display)

> e. Close current recordset

> f. Close db-connection

> g. Loop next

> h. Calculate time

>

> Result:

> ASP+: 18.0 secs.

> ASP: 18 secs.

>

> Comments on test #2:

> It clearly shows that the SQLDataReader is outperforming the ADODB 

Records

> by atleast 50%. Nice, but not as fast as one would want - we're 

talking

> SQL Server optimized code here .. come on! ASP is clearly getting a 

lot

> slower when it's going to do something with that connection, instead 

of

> just using the 'proxy' (or whatever).

>

> -- =3D --

>

> Test #3:

>

> Please notice that I've left the opening/closing of the db-connection 



> outside of the loop - just to see the difference. You'll like the 

outcome:

>

> Pseudocode:

> a. Open db-connection to SQL Server

> b. Do a loop with 1000 iterations

> c. Create a recordset and perform a simple select.

> d. Loop through all records in each recordset (no display)

> e. Close current recordset

> f. Loop next

> g. Close db-connection

> h. Calculate time

>

> Result:

> ASP+: 4.0 secs.

> ASP: 16 secs.

>

> Comments on test #3:

> The SQL Server namespace is obviously gaining a lot of performance 

once it

> got rid of the open/close connection code in each iteration. But, how 

come

> it's really that slow on it? I'd expected the SQL Server namespace to 



> perform just as fast as the ASP, using the proxy method and only take 

a

> performance-hit once data starts to flow.

>

> Question (and discussion):

> When programming datalayer-components using the .NET framework and 

the

> specific SQL Server optimized namespace, it would come with a big

> performance-penalty if you were to open a db-connection in each and 

every

> function of your datalayer.

>

> Unlike regular ASP - you can't (in ASPx) declare a set of global 

variables

> for your page (e.g. oConn =3D valid database-connection) because 

everything

> actually is a self-contained assembly. Thus, variables have assembly 

level

> scope.

>

> Compared to regular ASP, I can't use the global variable holding the

> connection for the entire page (e. g. oConn) and use that very 

connection

> in an include-file or pagelet. I'll have to create my own connection 

in

> each and every part of the assembly.

>

> As the above test shows, then you're actually making your application 

'N'

> times slower for each function you're calling in the code (provided 

those

> functions need database-connections), because each function would 

need a

> database-connection. The same goes for ASP, but you can still rely on 



> the 'global' connection-variable. So, what do we do? We need to 

eliminate

> the overhead and look at a solution.

>

> Theory:

> I've given this a lot of thought and the only solution would be to 

make

> a 'rule', which says that the calling function should always provide 

a

> valid database-connection to the data-layer when it requests data. 

This

> would ensure multi-use of the same db-connection (when it's passed as 

an

> function-argument like the following):

>

> (C#):

> // Master function always providing a 'global' connection as 

function-argument

> public void Master() {

>     SQLConnection oConn =3D new SQLConnection

>     // More oConn code here gives a valid connection

>     string strPage =3D GetPages(oConn, 20, 10);

>     string strColumn =3D GetColumns(oConn, 20);

> }

>

> public void GetPages(SQLConnection oConn, int intPageId, int 

intRowCount) {

>     // Use oConn as provided connection and remember to check for 

validity

> }

>

> public void GetColumns(SQLConnection oConn, int intNumCols) {

>     // Use oConn as provided connection and remember to check for 

validity

> }

>

> It just seems really *weird* to always pass a db-connection as a 

argument

> when you've been used to having global variables available. I know,

> globals are bad, but for db-connections they're really nice.

>

> I really hope you'll willing to join the discussion. We must adhere 

to the

> best solution at all times - which is why I'm asking this before 

starting

> to do the work here.

>

> Thanks in advance!

>

> With Regards

> Anders Lundholm - lundholm@s...

> --



Message #6 by Scott Mauvais <smauvais@m...> on Tue, 28 Nov 2000 07:29:27 -0800
Scott,



Won't you run into some serious scalability issues if you are holding all

those open connections?



Also, you are building dependency between your business and data layers.

Yes, if you change providers you can always update your connection

string....but what if you decided you need to use two (or three) different

providers rather than the single one your business objects assume.



--scott

MCS





> -----Original Message-----

> From: Scott Davis [mailto:Scott.D@e...]

> Sent: Tuesday, November 28, 2000 5:22 AM

> To: ASP+

> Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection

> 

> 

> Frederik, there is one simple reason to pass around a 

> SQLConnection or ADOConnection.  Performance.  Our data-layer 

> is organized into objects.  Those objects are usually 

> persisted to a database table.  So, the problem with not 

> passing around the opened Connection object, is that I would 

> have to open a new connection in each of my data-layer 

> objects.  If one of my business layer methods, needs to 

> access two or more of my data-layer objects, then I have to 

> open a connection 2 or more times.  If I create one 

> Connection object and pass it in to the data-layer objects, I 

> only have to have one Connection object and I only have to 

> open it one time.

> 

> I somewhat agree with your assessment that the business layer 

> has a data dependency, but not so much as you are making it 

> out.  You business layer MUST have a data dependency, 

> otherwise, what good is it?  If I use the ADOConnection 

> object in the business layer, I'm still sheltered from any 

> changes in the data-layer as to the provider of my data.  The 

> business layer won't care where the data comes from.  Our 

> business layer access it's data from Collections in the 

> data-layer objects.  That part will never change, regardlesss 

> of where the data is coming from.  If you change providers or 

> servers or whatever, you simply change your Connection 

> String(s) in one central place...real simple.

> 

> Any downside to creating and opening the connection objects 

> in my business layer is far less than the downside and the 

> performance loss that I will incur by creating and opening 

> multiple Connection objects.

> 

> Scott Davis

> MCSD, MCP

> International Parts

> Decision Consultants Inc.

> 

> 

> -----Original Message-----

> From: Fredrik Normen [mailto:fredrik.normen@e...]

> Sent: Tuesday, November 28, 2000 4:23 AM

> To: ASP+

> Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection

> 

> 

> > Your conclusion is correct.  We've been working on a rather 

> large project

> > here using ASP.NET and C# for the past 3 months.  This is 

> exactly what we

> > are doing.  You ALWAYS want to limit the amount of times 

> that you are 

> > opening and closing a connection to a database, as your 

> tests show, it is

> > rather expensive.  All of our data-layer components either take a 

> > SQLConnection object as a parameter in the constructor or 

> have methods 

> > that take a SQLConnection as a parameter.

> 

> 

> You mean you pass a SQLConnection from the business layer ?

> If so you will have a data dependency in the business layer 

> and it's not

> very nice. The business layer should not know where the data 

> comes from.

> And even if you do so, the connection must be maid somewhere 

> else and what

> we have seen is that ADO handles connections much faster then ADO.NET.

> 

> A connection in ADO.Net must be faster than a connection in ADO, or

> Microsoft will have problems with this, because if you have 

> 100 users at

> the same time they will each do a connection with ADO.NET, 

> and if we look

> at the test this is very time consuming. To increase scalability and

> performance in ASP.NET the ADO.NET must be much faster, even 

> if we think

> in terms of OO.

> 

> I will never tolerate this bad result, in the final release 

> of ADO.Net I

> wan't to see big changes, I want to se that ADO.NET is much 

> faster than

> ADO or Microsoft have failed with ADO.NET.

> 

> /Fredrik Normen

> 

> 

> 

> 

> > 

> > -----Original Message-----

> > From: Anders Lundholm [mailto:lundholm@s...]

> > Sent: Monday, November 27, 2000 11:03 AM

> > To: ASP+

> > Subject: [aspx] SQLConnection speed vs. ADODB.Connection

> > 

> > 

> > Hello people!

> > 

> > I am eager to see just how fast the SQL Server specific 

> namespace is in

> > the .NET framework when compared to the older ADODB COM 

> components. Thus I

> > decided to write a simple performance test where ASPx and 

> ASP was supposed

> > to compete.

> > 

> > Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0

> > 

> > This is a long letter but I think it covers some questions a lot of 

> > current and prospective db-programmers ask: Which is 

> faster, when and why - and how can I take advantage of each?!

> > 

> > 

> > I have a question in the bottom of this mail, so please 

> take your time to

> > read this throroughly and try to answer my question if possible!

> > 

> > -- = --

> > 

> > Test #1:

> > Pseudocode:

> > a. Do a loop with 1000 iterations

> > b. Open db-connection to SQL Server

> > c. Close db-connection

> > d. Loop next

> > e. Calculate time

> > 

> > Result:

> > ASP+: 8.0 secs.

> > ASP: 0.64 secs.

> > 

> > Comments on test #1:

> > This is very strange. I know ASP is really good at 

> communicating with the

> > ODBC layer, but this is scarry. The only answer I can come 

> up with is, the

> > ASP Connection object isn't opening a 'real' connection to 

> the SQL Server -

> >  just a 'proxy' of that connection. Once the first data 

> starts to flow 

> > to/from through that proxy, ASP will ask for a 'real' connection.

> > 

> > The other answer is, that the .NET framework haven't 

> incorporated proper

> > connection-pooling for the SQL Server namespace yet (which 

> I really hope -

> > look at those numbers!). Thus, the ASPx example opens a 

> 'real' database-

> > connection to the SQL Server, which naturally is heavier 

> (the below test

> > kinda supports that theory).

> > 

> > No-one would - under all circumstances - open/close a 

> connection without

> > doing anything with it first! Only me, I guess! :)

> > 

> > -- = --

> > 

> > Test #2:

> > Pseudocode:

> > a. Do a loop with 1000 iterations

> > b. Open db-connection to SQL Server

> > c. Create a recordset and perform a simple select.

> > d. Loop through all records in each recordset (no display)

> > e. Close current recordset

> > f. Close db-connection

> > g. Loop next

> > h. Calculate time

> > 

> > Result:

> > ASP+: 18.0 secs.

> > ASP: 18 secs.

> > 

> > Comments on test #2:

> > It clearly shows that the SQLDataReader is outperforming 

> the ADODB Records

> > by atleast 50%. Nice, but not as fast as one would want - 

> we're talking

> > SQL Server optimized code here .. come on! ASP is clearly 

> getting a lot

> > slower when it's going to do something with that 

> connection, instead of

> > just using the 'proxy' (or whatever).

> > 

> > -- = --

> > 

> > Test #3:

> > 

> > Please notice that I've left the opening/closing of the 

> db-connection 

> > outside of the loop - just to see the difference. You'll 

> like the outcome:

> > 

> > Pseudocode:

> > a. Open db-connection to SQL Server

> > b. Do a loop with 1000 iterations

> > c. Create a recordset and perform a simple select.

> > d. Loop through all records in each recordset (no display)

> > e. Close current recordset

> > f. Loop next

> > g. Close db-connection

> > h. Calculate time

> > 

> > Result:

> > ASP+: 4.0 secs.

> > ASP: 16 secs.

> > 

> > Comments on test #3:

> > The SQL Server namespace is obviously gaining a lot of 

> performance once it

> > got rid of the open/close connection code in each 

> iteration. But, how come

> > it's really that slow on it? I'd expected the SQL Server 

> namespace to 

> > perform just as fast as the ASP, using the proxy method and 

> only take a

> > performance-hit once data starts to flow.

> > 

> > Question (and discussion):

> > When programming datalayer-components using the .NET 

> framework and the 

> > specific SQL Server optimized namespace, it would come with a big 

> > performance-penalty if you were to open a db-connection in 

> each and every

> > function of your datalayer.

> > 

> > Unlike regular ASP - you can't (in ASPx) declare a set of 

> global variables

> > for your page (e.g. oConn = valid database-connection) 

> because everything

> > actually is a self-contained assembly. Thus, variables have 

> assembly level

> > scope.

> > 

> > Compared to regular ASP, I can't use the global variable 

> holding the 

> > connection for the entire page (e. g. oConn) and use that 

> very connection

> > in an include-file or pagelet. I'll have to create my own 

> connection in

> > each and every part of the assembly.

> > 

> > As the above test shows, then you're actually making your 

> application 'N'

> > times slower for each function you're calling in the code 

> (provided those

> > functions need database-connections), because each function 

> would need a

> > database-connection. The same goes for ASP, but you can 

> still rely on 

> > the 'global' connection-variable. So, what do we do? We 

> need to eliminate

> > the overhead and look at a solution.

> > 

> > Theory:

> > I've given this a lot of thought and the only solution 

> would be to make

> > a 'rule', which says that the calling function should 

> always provide a 

> > valid database-connection to the data-layer when it 

> requests data. This

> > would ensure multi-use of the same db-connection (when it's 

> passed as an

> > function-argument like the following):

> > 

> > (C#):

> > // Master function always providing a 'global' connection 

> as function-argument

> > public void Master() {

> >     SQLConnection oConn = new SQLConnection

> >     // More oConn code here gives a valid connection

> >     string strPage = GetPages(oConn, 20, 10);

> >     string strColumn = GetColumns(oConn, 20);

> > }

> > 

> > public void GetPages(SQLConnection oConn, int intPageId, 

> int intRowCount) {

> >     // Use oConn as provided connection and remember to 

> check for validity

> > }

> > 

> > public void GetColumns(SQLConnection oConn, int intNumCols) {

> >     // Use oConn as provided connection and remember to 

> check for validity

> > }

> > 

> > It just seems really *weird* to always pass a db-connection 

> as a argument

> > when you've been used to having global variables available. I know, 

> > globals are bad, but for db-connections they're really nice.

> > 

> > I really hope you'll willing to join the discussion. We 

> must adhere to the

> > best solution at all times - which is why I'm asking this 

> before starting

> > to do the work here. 

> > 

> > Thanks in advance!

> > 

> > With Regards

> > Anders Lundholm - lundholm@s...

> > --

> 

> 

Message #7 by =?iso-8859-1?Q?Fredrik_Norm=E9n?= <fredrik.normen@e...> on Tue, 28 Nov 2000 17:01:57 +0100
Hi,



Comments inline.



>Frederik, there is one simple reason to pass around a SQLConnection or

ADOConnection.

>Performance.  Our data-layer is organized into objects.  Those objects are

usually persisted to a

>database table.  So, the problem with not passing around the opened

Connection object, is that I would have to >open a new connection in each of

my data-layer objects.  If one of my business layer methods, needs to access

>two or more of my data-layer objects, then I have to open a connection 2 or

more times.  If I create one

>Connection object and pass it in to the data-layer objects, I only have to

have one Connection object and I

>only have to open it one time.



Ok, I have sometimes the same problem, but I consider of having a better

design of the system and the ability to manage and change the component

depending on the markets needs, without affecting other layers.

You can solve some of the connection problems with Object pooling.



>I somewhat agree with your assessment that the business layer has a data

dependency, but not so much as you are >making it out.  You business layer

MUST have a data dependency, otherwise, what good is it?



What I ment was that Business object should not know where the data comes

from.

The Business objects should only get data from the data object or the

presentation layer, this will give us a better way to change each layer

without affecting others.

For example maybe we have to change data objects to get information from a

Oracle database.

In order to do is we have to change our SQLCOnnection to ADOConnection and

use OLEDB Providers.

This will affect both the Busniess and data layer in your example.

Maybe we want to get data from a SAP/R3 system, we want to do this without

changing the business objects.



>If I use the ADOConnection object in the business layer, I'm still

sheltered from any changes in the data-layer >as to the provider of my data.

The business layer won't care where the data comes from.  Our business layer

>access it's data from Collections in the data-layer objects.  That part

will never change, regardlesss of where >the data is coming from.  If you

change providers or servers or whatever, you simply change your Connection

>String(s) in one central place...real simple.



Sometimes you need to change more than the connection string.



>Any downside to creating and opening the connection objects in my business

layer is far less than the downside >and the performance loss that I will

incur by creating and opening multiple Connection objects.



I'm aware of the fact that performance and scalability is very important,

but it's very important to change the objects according to the market.. And

it's important for developer to do this in an easy way.



/Fredrik Normén



Message #8 by Scott Davis <Scott.D@e...> on Tue, 28 Nov 2000 13:23:22 -0500
Frederik, I think I answered most of what you said here in a previous 

post when I explained how we have encapsulated our connection object 

creation and opening in a separate object.  By doing that, the business 

layer, never has to change, only the data-layer.



I think we are saying the same thing here, but our approach is slightly 

different.  In your approach, how do you prevent having to create and 

open many different connections if you are not passing a connection 

object around (which is simply a point that you are passing)??  If you 

are creating, opening and closing several different connections, this 

is not what we want to do here.  It may work fine for your application, 

but it won't work for ours and I don't want to put that kind of load of 

Database server.



Scott Davis

MCSD, MCP

International Parts

Decision Consultants Inc.





-----Original Message-----

From: Fredrik Norm=E9n [mailto:fredrik.normen@e...]

Sent: Tuesday, November 28, 2000 11:02 AM

To: ASP+

Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection





Hi,



Comments inline.



>Frederik, there is one simple reason to pass around a SQLConnection or

ADOConnection.

>Performance.  Our data-layer is organized into objects.  Those objects 

are

usually persisted to a

>database table.  So, the problem with not passing around the opened

Connection object, is that I would have to >open a new connection in 

each of

my data-layer objects.  If one of my business layer methods, needs to 

access

>two or more of my data-layer objects, then I have to open a connection 

2 or

more times.  If I create one

>Connection object and pass it in to the data-layer objects, I only 

have to

have one Connection object and I

>only have to open it one time.



Ok, I have sometimes the same problem, but I consider of having a 

better

design of the system and the ability to manage and change the component

depending on the markets needs, without affecting other layers.

You can solve some of the connection problems with Object pooling.



>I somewhat agree with your assessment that the business layer has a 

data

dependency, but not so much as you are >making it out.  You business 

layer

MUST have a data dependency, otherwise, what good is it?



What I ment was that Business object should not know where the data 

comes

from.

The Business objects should only get data from the data object or the

presentation layer, this will give us a better way to change each layer

without affecting others.

For example maybe we have to change data objects to get information 

from a

Oracle database.

In order to do is we have to change our SQLCOnnection to ADOConnection 

and

use OLEDB Providers.

This will affect both the Busniess and data layer in your example.

Maybe we want to get data from a SAP/R3 system, we want to do this 

without

changing the business objects.



>If I use the ADOConnection object in the business layer, I'm still

sheltered from any changes in the data-layer >as to the provider of my 

data.

The business layer won't care where the data comes from.  Our business 

layer

>access it's data from Collections in the data-layer objects.  That 

part

will never change, regardlesss of where >the data is coming from.  If 

you

change providers or servers or whatever, you simply change your 

Connection

>String(s) in one central place...real simple.



Sometimes you need to change more than the connection string.



>Any downside to creating and opening the connection objects in my 

business

layer is far less than the downside >and the performance loss that I 

will

incur by creating and opening multiple Connection objects.



I'm aware of the fact that performance and scalability is very 

important,

but it's very important to change the objects according to the market.. 

And

it's important for developer to do this in an easy way.



/Fredrik Norm=E9n





Message #9 by Scott Davis <Scott.D@e...> on Tue, 28 Nov 2000 13:18:44 -0500
I'm running much less risk of scalability issues with my approach, which 

opens a connection once, uses it and closes it.  Maybe you are mis-

interpreting or missed what we are doing here.  We are working on an 

ASP.NET/C# project.  All data access is done each time a page loads on the 

server.  Therefore, we create ONE connection object, use it, close it and 

then throw it away.  As opposed to creating and opening several connection 

objects, using them, closing them and throwing them all away.



One of earlier posts answered your second question.  All of our 

SQLConnection objects are encapsulated in a separate object.  If we needed 

to use two or three different providers (which isn't realistic on this 

project), we would simply encapsulate those new connections in this 

separate object.  The business layer wouldn't change at all on the data-

layer.



Scott Davis

MCSD, MCP

International Parts

Decision Consultants Inc.





-----Original Message-----

From: Scott Mauvais [mailto:smauvais@m...]

Sent: Tuesday, November 28, 2000 10:29 AM

To: ASP+

Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection





Scott,



Won't you run into some serious scalability issues if you are holding all

those open connections?



Also, you are building dependency between your business and data layers.

Yes, if you change providers you can always update your connection

string....but what if you decided you need to use two (or three) different

providers rather than the single one your business objects assume.



--scott

MCS





> -----Original Message-----

> From: Scott Davis [mailto:Scott.D@e...]

> Sent: Tuesday, November 28, 2000 5:22 AM

> To: ASP+

> Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection

> 

> 

> Frederik, there is one simple reason to pass around a 

> SQLConnection or ADOConnection.  Performance.  Our data-layer 

> is organized into objects.  Those objects are usually 

> persisted to a database table.  So, the problem with not 

> passing around the opened Connection object, is that I would 

> have to open a new connection in each of my data-layer 

> objects.  If one of my business layer methods, needs to 

> access two or more of my data-layer objects, then I have to 

> open a connection 2 or more times.  If I create one 

> Connection object and pass it in to the data-layer objects, I 

> only have to have one Connection object and I only have to 

> open it one time.

> 

> I somewhat agree with your assessment that the business layer 

> has a data dependency, but not so much as you are making it 

> out.  You business layer MUST have a data dependency, 

> otherwise, what good is it?  If I use the ADOConnection 

> object in the business layer, I'm still sheltered from any 

> changes in the data-layer as to the provider of my data.  The 

> business layer won't care where the data comes from.  Our 

> business layer access it's data from Collections in the 

> data-layer objects.  That part will never change, regardlesss 

> of where the data is coming from.  If you change providers or 

> servers or whatever, you simply change your Connection 

> String(s) in one central place...real simple.

> 

> Any downside to creating and opening the connection objects 

> in my business layer is far less than the downside and the 

> performance loss that I will incur by creating and opening 

> multiple Connection objects.

> 

> Scott Davis

> MCSD, MCP

> International Parts

> Decision Consultants Inc.

> 

> 

> -----Original Message-----

> From: Fredrik Normen [mailto:fredrik.normen@e...]

> Sent: Tuesday, November 28, 2000 4:23 AM

> To: ASP+

> Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection

> 

> 

> > Your conclusion is correct.  We've been working on a rather 

> large project

> > here using ASP.NET and C# for the past 3 months.  This is 

> exactly what we

> > are doing.  You ALWAYS want to limit the amount of times 

> that you are 

> > opening and closing a connection to a database, as your 

> tests show, it is

> > rather expensive.  All of our data-layer components either take a 

> > SQLConnection object as a parameter in the constructor or 

> have methods 

> > that take a SQLConnection as a parameter.

> 

> 

> You mean you pass a SQLConnection from the business layer ?

> If so you will have a data dependency in the business layer 

> and it's not

> very nice. The business layer should not know where the data 

> comes from.

> And even if you do so, the connection must be maid somewhere 

> else and what

> we have seen is that ADO handles connections much faster then ADO.NET.

> 

> A connection in ADO.Net must be faster than a connection in ADO, or

> Microsoft will have problems with this, because if you have 

> 100 users at

> the same time they will each do a connection with ADO.NET, 

> and if we look

> at the test this is very time consuming. To increase scalability and

> performance in ASP.NET the ADO.NET must be much faster, even 

> if we think

> in terms of OO.

> 

> I will never tolerate this bad result, in the final release 

> of ADO.Net I

> wan't to see big changes, I want to se that ADO.NET is much 

> faster than

> ADO or Microsoft have failed with ADO.NET.

> 

> /Fredrik Normen

> 

> 

> 

> 

> > 

> > -----Original Message-----

> > From: Anders Lundholm [mailto:lundholm@s...]

> > Sent: Monday, November 27, 2000 11:03 AM

> > To: ASP+

> > Subject: [aspx] SQLConnection speed vs. ADODB.Connection

> > 

> > 

> > Hello people!

> > 

> > I am eager to see just how fast the SQL Server specific 

> namespace is in

> > the .NET framework when compared to the older ADODB COM 

> components. Thus I

> > decided to write a simple performance test where ASPx and 

> ASP was supposed

> > to compete.

> > 

> > Dual PII-350Mhz, 256Mb, 100Gb UW and Win2K Server/SQL Server 7.0

> > 

> > This is a long letter but I think it covers some questions a lot of 

> > current and prospective db-programmers ask: Which is 

> faster, when and why - and how can I take advantage of each?!

> > 

> > 

> > I have a question in the bottom of this mail, so please 

> take your time to

> > read this throroughly and try to answer my question if possible!

> > 

> > -- = --

> > 

> > Test #1:

> > Pseudocode:

> > a. Do a loop with 1000 iterations

> > b. Open db-connection to SQL Server

> > c. Close db-connection

> > d. Loop next

> > e. Calculate time

> > 

> > Result:

> > ASP+: 8.0 secs.

> > ASP: 0.64 secs.

> > 

> > Comments on test #1:

> > This is very strange. I know ASP is really good at 

> communicating with the

> > ODBC layer, but this is scarry. The only answer I can come 

> up with is, the

> > ASP Connection object isn't opening a 'real' connection to 

> the SQL Server -

> >  just a 'proxy' of that connection. Once the first data 

> starts to flow 

> > to/from through that proxy, ASP will ask for a 'real' connection.

> > 

> > The other answer is, that the .NET framework haven't 

> incorporated proper

> > connection-pooling for the SQL Server namespace yet (which 

> I really hope -

> > look at those numbers!). Thus, the ASPx example opens a 

> 'real' database-

> > connection to the SQL Server, which naturally is heavier 

> (the below test

> > kinda supports that theory).

> > 

> > No-one would - under all circumstances - open/close a 

> connection without

> > doing anything with it first! Only me, I guess! :)

> > 

> > -- = --

> > 

> > Test #2:

> > Pseudocode:

> > a. Do a loop with 1000 iterations

> > b. Open db-connection to SQL Server

> > c. Create a recordset and perform a simple select.

> > d. Loop through all records in each recordset (no display)

> > e. Close current recordset

> > f. Close db-connection

> > g. Loop next

> > h. Calculate time

> > 

> > Result:

> > ASP+: 18.0 secs.

> > ASP: 18 secs.

> > 

> > Comments on test #2:

> > It clearly shows that the SQLDataReader is outperforming 

> the ADODB Records

> > by atleast 50%. Nice, but not as fast as one would want - 

> we're talking

> > SQL Server optimized code here .. come on! ASP is clearly 

> getting a lot

> > slower when it's going to do something with that 

> connection, instead of

> > just using the 'proxy' (or whatever).

> > 

> > -- = --

> > 

> > Test #3:

> > 

> > Please notice that I've left the opening/closing of the 

> db-connection 

> > outside of the loop - just to see the difference. You'll 

> like the outcome:

> > 

> > Pseudocode:

> > a. Open db-connection to SQL Server

> > b. Do a loop with 1000 iterations

> > c. Create a recordset and perform a simple select.

> > d. Loop through all records in each recordset (no display)

> > e. Close current recordset

> > f. Loop next

> > g. Close db-connection

> > h. Calculate time

> > 

> > Result:

> > ASP+: 4.0 secs.

> > ASP: 16 secs.

> > 

> > Comments on test #3:

> > The SQL Server namespace is obviously gaining a lot of 

> performance once it

> > got rid of the open/close connection code in each 

> iteration. But, how come

> > it's really that slow on it? I'd expected the SQL Server 

> namespace to 

> > perform just as fast as the ASP, using the proxy method and 

> only take a

> > performance-hit once data starts to flow.

> > 

> > Question (and discussion):

> > When programming datalayer-components using the .NET 

> framework and the 

> > specific SQL Server optimized namespace, it would come with a big 

> > performance-penalty if you were to open a db-connection in 

> each and every

> > function of your datalayer.

> > 

> > Unlike regular ASP - you can't (in ASPx) declare a set of 

> global variables

> > for your page (e.g. oConn = valid database-connection) 

> because everything

> > actually is a self-contained assembly. Thus, variables have 

> assembly level

> > scope.

> > 

> > Compared to regular ASP, I can't use the global variable 

> holding the 

> > connection for the entire page (e. g. oConn) and use that 

> very connection

> > in an include-file or pagelet. I'll have to create my own 

> connection in

> > each and every part of the assembly.

> > 

> > As the above test shows, then you're actually making your 

> application 'N'

> > times slower for each function you're calling in the code 

> (provided those

> > functions need database-connections), because each function 

> would need a

> > database-connection. The same goes for ASP, but you can 

> still rely on 

> > the 'global' connection-variable. So, what do we do? We 

> need to eliminate

> > the overhead and look at a solution.

> > 

> > Theory:

> > I've given this a lot of thought and the only solution 

> would be to make

> > a 'rule', which says that the calling function should 

> always provide a 

> > valid database-connection to the data-layer when it 

> requests data. This

> > would ensure multi-use of the same db-connection (when it's 

> passed as an

> > function-argument like the following):

> > 

> > (C#):

> > // Master function always providing a 'global' connection 

> as function-argument

> > public void Master() {

> >     SQLConnection oConn = new SQLConnection

> >     // More oConn code here gives a valid connection

> >     string strPage = GetPages(oConn, 20, 10);

> >     string strColumn = GetColumns(oConn, 20);

> > }

> > 

> > public void GetPages(SQLConnection oConn, int intPageId, 

> int intRowCount) {

> >     // Use oConn as provided connection and remember to 

> check for validity

> > }

> > 

> > public void GetColumns(SQLConnection oConn, int intNumCols) {

> >     // Use oConn as provided connection and remember to 

> check for validity

> > }

> > 

> > It just seems really *weird* to always pass a db-connection 

> as a argument

> > when you've been used to having global variables available. I know, 

> > globals are bad, but for db-connections they're really nice.

> > 

> > I really hope you'll willing to join the discussion. We 

> must adhere to the

> > best solution at all times - which is why I'm asking this 

> before starting

> > to do the work here. 

> > 

> > Thanks in advance!

> > 

> > With Regards

> > Anders Lundholm - lundholm@s...

> > --

> 

> 



---

Wrox Professional Web Developer Conference II

http://www.wroxconferences.com/WebDevEurope

November 29th - December 1st 2000, Amsterdam, Netherlands

Create powerful distributed web applications serving you now and

in the future. From ASP+ and VB.NET to XML and SQL Server 2000




Message #10 by "Anders Lundholm" <lundholm@s...> on Tue, 28 Nov 2000 19:54:49 +0100
Hello!



Comments inline!



> You can solve some of the connection problems with Object pooling.



I thought ASP.NET used object pooling?! Isn't all .aspx files compiled and

pooled?! Is it only true components (which have been compiled) that are able

to achieve pooling?! Sounds weird, because .aspx files are assemblies and

compiled too. Thus .aspx should be able to get the same speed as components.



How would you make your datalayer faster then?



> What I ment was that Business object should not know where the data comes

> from.



True! But, how would the datalayer its connection string!?

Would you hardcode the connection-string in the datalayer (not) - or just

hardcode the retrieval of e.g. a DSN from an Application variable or

something else?! I mean, using an argument in the function call would make

it dynamic!



I agree it would affect atlest one more layer if you decided to use e.g. a

db-connection or just a db-DSN string as argument to a constructor or

function-call *because* the argument would become obsolete if you decided to

use the ADO namespace instead of the SQL namespace. This would leave you

with a lot of code which provided SQLConnection arguments to the

constructors/functions instead of the current ADO connection. Is this right?



> The Business objects should only get data from the data object or the

> presentation layer, this will give us a better way to change each layer

> without affecting others.

> For example maybe we have to change data objects to get information from a

> Oracle database.

> In order to do is we have to change our SQLCOnnection to ADOConnection and

> use OLEDB Providers.

> This will affect both the Busniess and data layer in your example.



> Maybe we want to get data from a SAP/R3 system, we want to do this without

> changing the business objects.



When you're talking about different datalayers, how often do you really

change e.g. a SQLConnection to a SAP/R3 connection?



I mean, when I'm building the datalayer for my application, then there will

be parts of that layer which will never change providers, thus allowing me

to use a connection as constructor/argument would give me a faster

datalayer. If I'm doing - lets say - 10 database lookups, why would I want

to sacrifice the speed for more encapsulation?!



You're right Fredrik, but I believe there's a middleway. Some parts of your

datalayer will always want to connect to a DB such as SQL Server (or an ADO

provider). Or?



> Sometimes you need to change more than the connection string.



True, but if you do that, then it's also possible that the consumer (e.g.

the businesslayer) would want to handle the data different. Thus you're

basically changing core components and why not optimize those as well?!



I can follow you all the way, except that I really don't get HOW you'd

specify which DB provider to use in your datalayer if you aren't giving it

as an argument (I bet you're NOT hardcoding the DSN string).



> I'm aware of the fact that performance and scalability is very important,

> but it's very important to change the objects according to the market..

And

> it's important for developer to do this in an easy way.



Naturally, but you really have to sit back and see how frequent you'll want

to change parts of your datalayer. When it comes to datalayers which connect

to variable systems such as CRMs or - heck - even 3rd-party .NET components,

you should really want to encapsulate as much as possible.



But, when it comes to cornerstone parts of your application where DB

connections could potentially drag your site to the dust, I would certainly

optimize as much as possible.



The issue in Scotts and my case is (as I see it), to choose if we want to

specify a SQLConnection or a ADOConnection as an argument. The latter is

more flexible but the former is faster (SQLConnection).



What do you think about this?

Please enlighten me if I'm off here .. I'd want to do it the right way!



with regards

anders lundholm ˇ lundholm@s...

the sphereworx / monoliner experience

--





Message #11 by =?iso-8859-1?Q?Fredrik_Norm=E9n?= <fredrik.normen@e...> on Wed, 29 Nov 2000 09:30:41 +0100
>I thought ASP.NET used object pooling?! Isn't all .aspx files compiled and

>pooled?! Is it only true components (which have been compiled) that are

able

>to achieve pooling?! Sounds weird, because .aspx files are assemblies and

>compiled too. Thus .aspx should be able to get the same speed as

components.



No, this is not true, the only way to use object pooling is to use Component

Services today with the .Net



Here is a snap from the .Net Framwork Developers Guide:



<SNAP>

Connection Pooling

To deploy high-performance applications, you need to use connection pooling.

When you use the ADO Managed Provider you do not need to enable connection

pooling, because the ADO Managed Provider does so automatically. The SQL

Managed Provider relies on Windows 2000 Component Services to provide

connection pooling, and you need to follow these steps to enable it:



Define the SQLConnection subclass using the code provided below.

Write the code to use the pooled connection.

Include Microsoft.ComServices.dll.

Optionally, configure the pooling characteristics of the component using the

component services user interface.

Defining the SQLConnection Subclass

The following code defines a subclass of the SQLConnection class. Use

Guidgen.exe to obtain a new Guid (FD5ABffd-D026-4684-8515-2BB5184E8991 in

the sample below).



[ConstructionEnabled(default="Server=servername ?"]   // required here or in

gui

[ObjectPooling(true)]                      // required

[Transaction(TransactionOption.Supported)] // optional

public class myConnection : SQLPooledConnection

{

// class is empty unless adding SetComplete and SetAbort methods, e.g.

// public void SetComplete() { ContextUtil.SetComplete(); }

// public void SetAbort() { ContextUtil.SetAbort(); }

}

Writing Code That Uses the Pooled Component

The pooled connection class is used much like an ordinary SQLConnection, as

shown in the following code sample:



IReader iReader;



myConnection conn = new myConnection();

conn.Open

SQLCommand cmd = new SQLCommand("SELECT * FROM Orders", conn);

cmd.Execute(ref iReader);



conn.Close();

The model for pooled connection is the same for pooled and non-pooled

connections. However, it is especially important to call Close when you

finish with a pooled connection to release it back into the pool.



Include Microsoft.ComServices.dll

The COM+ Services DLL must be included to support pooling.



Configuring Pooled Component

Although a pooled connection object can be strictly configured by setting

attributes at compile time, it is often desirable to change the behavior of

the object after the application has been deployed. To enable this,

attributes such as the connection string (also called the construction

string) and transaction requirements can be set with Component Services in

Administrative Tools.



Transaction Enlistment

One of the benefits of the pooling mechanism is that it provides support for

controlling transaction enlistment behavior. The SQL Managed provider

determines if the current context has a distributed transaction associated

with it, and if so, enlists automatically. You can control transaction

enlistment behavior of a pooled connection at compile time with

TransactionAttribute or at runtime with Component Services in Administrative

Tools.

</SNAP>



>True! But, how would the datalayer its connection string!?

>Would you hardcode the connection-string in the datalayer (not) - or just

>hardcode the retrieval of e.g. a DSN from an Application variable or

>something else?! I mean, using an argument in the function call would make

>it dynamic!



You can add the connection string to config.web, and use a shared propety

that read the connection string one time from the config.web file here is an

example:





config.web

-----------

<configuration>

    <!-- store the database connection info here -->

    <appsettings>

        <add key="DSN"

value="server=localhost;uid=sa;pwd=;database=northwind" />

    </appsettings>

</configuration>



Code

------------



using System;

using System.Web;

using System.Collections;



namespace MyApplication

{



    public class MyDBHelper {

static String ConnectionString;



public static String ConnectionString {



      get {

      	if (ConnectionString == null) {

			Hashtable appSettings = (Hashtable)

HttpContext.Current.GetConfig("appsettings");

                  m_ConnectionString = (String) appSettings["DSN"];



                  if (m_ConnectionString == null) {

                       throw new Exception("DSN Value not set in

Config.web");

                  }

             }

             return m_ConnectionString;

      }

}



If you want to get the connection string somewhere in you application you

simply write:



namespace MyApplication



	public class ProductsDB



        public DataSet GetProducts() {



            SQLConnection dbConnection = new

SQLConnection(MyDBHelper.ConnectionString);



.....



I hope this will give you some idea, you will find this in IbuySpy example.



>When you're talking about different datalayers, how often do you really

>change e.g. a SQLConnection to a SAP/R3 connection?



Not often, but if we have too, we must be pepeard to do it and in a simple

way.



>True, but if you do that, then it's also possible that the consumer (e.g.

>the businesslayer) would want to handle the data different. Thus you're

>basically changing core components and why not optimize those as well?!



No, the business layer will never work different because of changing the

data source, and so should it be designed. You should never need to change

the Business layer if you have to move or change the data-access object.

That is why you should seperate business from data.





/Fredrik Normén



Message #12 by Scott Davis <Scott.D@e...> on Wed, 29 Nov 2000 08:12:13 -0500
Frederik, I agree with pretty much everything that you've said here.  I 

think we're arriving at the same result in different fashions.



>>You can add the connection string to config.web, and use a shared 

propety

>>that read the connection string one time from the config.web file



This works great and we considered doing this.  The problem is if you 

want to use your data-layer components with a fat-client app, then 

you're hosed because you don't have a config.web file.  If don't intend 

to do that, then config.web is the perfect place for it.  We will 

probably be storing our DSNs somewhere that is accessible to all 

applications and easy to make global changes, such as Active Directory.



-----Original Message-----

From: Fredrik Norm=E9n [mailto:fredrik.normen@e...]

Sent: Wednesday, November 29, 2000 3:31 AM

To: ASP+

Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection





>I thought ASP.NET used object pooling?! Isn't all .aspx files compiled 

and

>pooled?! Is it only true components (which have been compiled) that 

are

able

>to achieve pooling?! Sounds weird, because .aspx files are assemblies 

and

>compiled too. Thus .aspx should be able to get the same speed as

components.



No, this is not true, the only way to use object pooling is to use 

Component

Services today with the .Net



Here is a snap from the .Net Framwork Developers Guide:



<SNAP>

Connection Pooling

To deploy high-performance applications, you need to use connection 

pooling.

When you use the ADO Managed Provider you do not need to enable 

connection

pooling, because the ADO Managed Provider does so automatically. The 

SQL

Managed Provider relies on Windows 2000 Component Services to provide

connection pooling, and you need to follow these steps to enable it:



Define the SQLConnection subclass using the code provided below.

Write the code to use the pooled connection.

Include Microsoft.ComServices.dll.

Optionally, configure the pooling characteristics of the component 

using the

component services user interface.

Defining the SQLConnection Subclass

The following code defines a subclass of the SQLConnection class. Use

Guidgen.exe to obtain a new Guid (FD5ABffd-D026-4684-8515-2BB5184E8991 

in

the sample below).



[ConstructionEnabled(default=3D"Server=3Dservername ..."]   // required 

here or in

gui

[ObjectPooling(true)]                      // required

[Transaction(TransactionOption.Supported)] // optional

public class myConnection : SQLPooledConnection

{

// class is empty unless adding SetComplete and SetAbort methods, e.g.

// public void SetComplete() { ContextUtil.SetComplete(); }

// public void SetAbort() { ContextUtil.SetAbort(); }

}

Writing Code That Uses the Pooled Component

The pooled connection class is used much like an ordinary 

SQLConnection, as

shown in the following code sample:



IReader iReader;



myConnection conn =3D new myConnection();

conn.Open

SQLCommand cmd =3D new SQLCommand("SELECT * FROM Orders", conn);

cmd.Execute(ref iReader);



conn.Close();

The model for pooled connection is the same for pooled and non-pooled

connections. However, it is especially important to call Close when you

finish with a pooled connection to release it back into the pool.



Include Microsoft.ComServices.dll

The COM+ Services DLL must be included to support pooling.



Configuring Pooled Component

Although a pooled connection object can be strictly configured by 

setting

attributes at compile time, it is often desirable to change the 

behavior of

the object after the application has been deployed. To enable this,

attributes such as the connection string (also called the construction

string) and transaction requirements can be set with Component Services 

in

Administrative Tools.



Transaction Enlistment

One of the benefits of the pooling mechanism is that it provides 

support for

controlling transaction enlistment behavior. The SQL Managed provider

determines if the current context has a distributed transaction 

associated

with it, and if so, enlists automatically. You can control transaction

enlistment behavior of a pooled connection at compile time with

TransactionAttribute or at runtime with Component Services in 

Administrative

Tools.

</SNAP>



>True! But, how would the datalayer its connection string!?

>Would you hardcode the connection-string in the datalayer (not) - or 

just

>hardcode the retrieval of e.g. a DSN from an Application variable or

>something else?! I mean, using an argument in the function call would 

make

>it dynamic!



You can add the connection string to config.web, and use a shared 

propety

that read the connection string one time from the config.web file here 

is an

example:





config.web

-----------

<configuration>

    <!-- store the database connection info here -->

    <appsettings>

        <add key=3D"DSN"

value=3D"server=3Dlocalhost;uid=3Dsa;pwd=3D;database=3Dnorthwind" />

    </appsettings>

</configuration>



Code

------------



using System;

using System.Web;

using System.Collections;



namespace MyApplication

{



    public class MyDBHelper {

static String ConnectionString;



public static String ConnectionString {



      get {

      	if (ConnectionString =3D=3D null) {

			Hashtable appSettings =3D (Hashtable)

HttpContext.Current.GetConfig("appsettings");

                  m_ConnectionString =3D (String) appSettings["DSN"];



                  if (m_ConnectionString =3D=3D null) {

                       throw new Exception("DSN Value not set in

Config.web");

                  }

             }

             return m_ConnectionString;

      }

}



If you want to get the connection string somewhere in you application 

you

simply write:



namespace MyApplication



	public class ProductsDB



        public DataSet GetProducts() {



            SQLConnection dbConnection =3D new

SQLConnection(MyDBHelper.ConnectionString);



.....



I hope this will give you some idea, you will find this in IbuySpy 

example.



>When you're talking about different datalayers, how often do you 

really

>change e.g. a SQLConnection to a SAP/R3 connection?



Not often, but if we have too, we must be pepeard to do it and in a 

simple

way.



>True, but if you do that, then it's also possible that the consumer 

(e.g.

>the businesslayer) would want to handle the data different. Thus 

you're

>basically changing core components and why not optimize those as 

well?!



No, the business layer will never work different because of changing 

the

data source, and so should it be designed. You should never need to 

change

the Business layer if you have to move or change the data-access 

object.

That is why you should seperate business from data.





/Fredrik Norm=E9n





Message #13 by =?iso-8859-1?Q?Fredrik_Norm=E9n?= <fredrik.normen@e...> on Wed, 29 Nov 2000 15:20:48 +0100
>Frederik, I agree with pretty much everything that you've said here.  I

think we're arriving at the

>same result in different fashions.



I think I can agree with this.



>This works great and we considered doing this.  The problem is if you want

to use your data-layer

>components with a fat-client app, then you're hosed because you don't have

a config.web file.  If don't >intend to do that, then config.web is the

perfect place for it.  We will probably be storing our DSNs

>somewhere that is accessible to all applications and easy to make global

changes, such as Active

>Directory.



If you are running a Web application you can get data from config.web or you

can use configmanager and read from you own config file.



example:



You config file:



<?xml version ="1.0"?>

<configuration xmlns="x-schema:catalog.xms">



  <Connection>Server=Localhost......</Connection>

</configuration>





C#

using System.Configuration;



String constring = (String) ConfigManager.GetProperty("Connection",

"c:\myapp\myconfig.cfg");





Maybe this will give you something.



Best Regards,

Fredrik Normén







-----Original Message-----

From: Fredrik Normén [mailto:fredrik.normen@e...]

Sent: Wednesday, November 29, 2000 3:31 AM

To: ASP+

Subject: [aspx] RE: SQLConnection speed vs. ADODB.Connection





>I thought ASP.NET used object pooling?! Isn't all .aspx files compiled and

>pooled?! Is it only true components (which have been compiled) that are

able

>to achieve pooling?! Sounds weird, because .aspx files are assemblies and

>compiled too. Thus .aspx should be able to get the same speed as

components.



No, this is not true, the only way to use object pooling is to use Component

Services today with the .Net



Here is a snap from the .Net Framwork Developers Guide:



<SNAP>

Connection Pooling

To deploy high-performance applications, you need to use connection pooling.

When you use the ADO Managed Provider you do not need to enable connection

pooling, because the ADO Managed Provider does so automatically. The SQL

Managed Provider relies on Windows 2000 Component Services to provide

connection pooling, and you need to follow these steps to enable it:



Define the SQLConnection subclass using the code provided below.

Write the code to use the pooled connection.

Include Microsoft.ComServices.dll.

Optionally, configure the pooling characteristics of the component using the

component services user interface.

Defining the SQLConnection Subclass

The following code defines a subclass of the SQLConnection class. Use

Guidgen.exe to obtain a new Guid (FD5ABffd-D026-4684-8515-2BB5184E8991 in

the sample below).



[ConstructionEnabled(default="Server=servername ..."]   // required here or

in

gui

[ObjectPooling(true)]                      // required

[Transaction(TransactionOption.Supported)] // optional

public class myConnection : SQLPooledConnection

{

// class is empty unless adding SetComplete and SetAbort methods, e.g.

// public void SetComplete() { ContextUtil.SetComplete(); }

// public void SetAbort() { ContextUtil.SetAbort(); }

}

Writing Code That Uses the Pooled Component

The pooled connection class is used much like an ordinary SQLConnection, as

shown in the following code sample:



IReader iReader;



myConnection conn = new myConnection();

conn.Open

SQLCommand cmd = new SQLCommand("SELECT * FROM Orders", conn);

cmd.Execute(ref iReader);



conn.Close();

The model for pooled connection is the same for pooled and non-pooled

connections. However, it is especially important to call Close when you

finish with a pooled connection to release it back into the pool.



Include Microsoft.ComServices.dll

The COM+ Services DLL must be included to support pooling.



Configuring Pooled Component

Although a pooled connection object can be strictly configured by setting

attributes at compile time, it is often desirable to change the behavior of

the object after the application has been deployed. To enable this,

attributes such as the connection string (also called the construction

string) and transaction requirements can be set with Component Services in

Administrative Tools.



Transaction Enlistment

One of the benefits of the pooling mechanism is that it provides support for

controlling transaction enlistment behavior. The SQL Managed provider

determines if the current context has a distributed transaction associated

with it, and if so, enlists automatically. You can control transaction

enlistment behavior of a pooled connection at compile time with

TransactionAttribute or at runtime with Component Services in Administrative

Tools.

</SNAP>



>True! But, how would the datalayer its connection string!?

>Would you hardcode the connection-string in the datalayer (not) - or just

>hardcode the retrieval of e.g. a DSN from an Application variable or

>something else?! I mean, using an argument in the function call would make

>it dynamic!



You can add the connection string to config.web, and use a shared propety

that read the connection string one time from the config.web file here is an

example:





config.web

-----------

<configuration>

    <!-- store the database connection info here -->

    <appsettings>

        <add key="DSN"

value="server=localhost;uid=sa;pwd=;database=northwind" />

    </appsettings>

</configuration>



Code

------------



using System;

using System.Web;

using System.Collections;



namespace MyApplication

{



    public class MyDBHelper {

static String ConnectionString;



public static String ConnectionString {



      get {

      	if (ConnectionString == null) {

			Hashtable appSettings = (Hashtable)

HttpContext.Current.GetConfig("appsettings");

                  m_ConnectionString = (String) appSettings["DSN"];



                  if (m_ConnectionString == null) {

                       throw new Exception("DSN Value not set in

Config.web");

                  }

             }

             return m_ConnectionString;

      }

}



If you want to get the connection string somewhere in you application you

simply write:



namespace MyApplication



	public class ProductsDB



        public DataSet GetProducts() {



            SQLConnection dbConnection = new

SQLConnection(MyDBHelper.ConnectionString);



.....



I hope this will give you some idea, you will find this in IbuySpy example.



>When you're talking about different datalayers, how often do you really

>change e.g. a SQLConnection to a SAP/R3 connection?



Not often, but if we have too, we must be pepeard to do it and in a simple

way.



>True, but if you do that, then it's also possible that the consumer (e.g.

>the businesslayer) would want to handle the data different. Thus you're

>basically changing core components and why not optimize those as well?!



No, the business layer will never work different because of changing the

data source, and so should it be designed. You should never need to change

the Business layer if you have to move or change the data-access object.

That is why you should seperate business from data.





/Fredrik Normén








  Return to Index