Click here to Skip to main content
Click here to Skip to main content

Stop writing connection management code every time you access the database

By , 6 Jan 2006
 

Contents

Introduction

This article showcases my AMS.ADO class library, which contains a set of classes used for executing database commands without the need for the typical connection management code. The classes are implemented into two separate assemblies -- one for .NET 2.0 (to take advantage of generics), the other for .NET 1.1 -- and are available for the four main providers: SQL Server, OLEDB, ODBC, and Oracle. Enjoy!

Background

When you want to run a database query or stored procedure, you typically follow the same set of steps every time:

  1. Create a command object and pass it the SQL for the query as well as a database connection object.
  2. If it's a stored procedure, set the CommandType to StoredProcedure.
  3. Set any parameters required for the query.
  4. Open the connection to the database.
  5. Execute the query and retrieve the records, if necessary.
  6. Close the database connection.

The code in C# typically looks like this:

using System.Data.SqlClient;
...
   
using (SqlConnection conn = new SqlConnection(connectionString))
{
   SqlCommand command = new SqlCommand("spUpdateDescription", conn);
   command.CommandType = CommandType.StoredProcedure;
    
   command.Parameters.Add("@ID", id);
   command.Parameters.Add("@Description", description);
    
   conn.Open();
   command.ExecuteNonQuery();
}

or in VB.NET 1.1:

Imports System.Data.SqlClient
...
    
Dim conn As New SqlConnection(connectionString)
         
Dim command As New SqlCommand("spUpdateDescription", conn)
command.CommandType = CommandType.StoredProcedure
    
command.Parameters.Add("@ID", id)
command.Parameters.Add("@Description", description)
    
Try          
   conn.Open()
   command.ExecuteNonQuery()
Finally
   conn.Dispose()
End Try

This logic needs to be repeated pretty much everywhere a query or stored procedure is executed. The reason is that the connection needs to be carefully managed so that it's opened and used only for the time required to access the database. Since this is a manual process, it's possible to inadvertently forget to close a connection after it's been used, which may cause the pool of connections to eventually reach its limit.

My solution to these issues is to wrap the four main IDbCommand classes (SqlCommand, OleDbCommand, OdbcCommand, and OracleCommand) into two sets of classes, which handle the connection management details behind the scenes for me.

Classes

The two classes are called SQL and StoredProcedure. They reduce the above six steps down to three:

  1. Create the SQL object and pass it the query (or stored procedure) as well as a database connection string or object.
  2. Set any parameters required for the query.
  3. Execute the query and retrieve the records, if necessary.

So, the above code looks like this in C#:

using AMS.ADO.SqlClient;
...
 
StoredProcedure sp = new 
    StoredProcedure("spUpdateDescription", connectionString);
    
sp.Parameters.Add("@ID", id);
sp.Parameters.Add("@Description", description);

sp.ExecuteNonQuery();

or in VB.NET:

Imports AMS.ADO.SqlClient
... 
        
Dim sp As New StoredProcedure("spUpdateDescription", connectionString)
    
sp.Parameters.Add("@ID", id)
sp.Parameters.Add("@Description", description)

sp.ExecuteNonQuery()

The same logic is now in five clear and simple lines of code, instead of ten (or twelve for VB.NET 1.1), with database access and connection management code mixed together. What a difference!

And it's not just the reduction in code, it's also not having to worry about leaving a connection open inadvertently. As you probably guessed, my ExecuteNonQuery creates and opens the connection, calls the real ExecuteNonQuery, and then closes the connection before returning the results. So, all that repetitive code is now where it should be: hidden away.

The above example is a simple (but realistic) case of writing to the database via a stored procedure. Since I pass a connection string to the constructor, the class creates and maintains the connection internally. If I had passed a connection object instead, it would have left it in the same open/closed state as it found it before the call to ExecuteNonQuery.

The StoredProcedure class derives most of its functionality from the SQL class. It's designed to eliminate the extra call to set the CommandType to StoredProcedure and to make it easy to search for stored procedure calls inside the code. The SQL class is designed for executing general SQL statements or queries (CRUD) against the database.

Let's look at another example, this time using the SQL class to execute a SELECT query in C#:

using AMS.ADO.SqlClient;
using System.Data.SqlClient;
...

using (SQL sql = new SQL("SELECT Description FROM" + 
          " SomeTable WHERE ID = @ID", connectionString))
{
   sql.Parameters.Add("@ID", id);

   for (SqlDataReader reader = sql.ExecuteReader(); reader.Read(); )
   {
      string description = reader.GetString(0);
      ...
   }
}

or in VB.NET 1.1:

Imports AMS.ADO.SqlClient
Imports System.Data.SqlClient
... 
       
Dim sql As New SQL("SELECT Description FROM" & _ 
         " SomeTable WHERE ID = @ID", connectionString)
sql.Parameters.Add("@ID", id)

Try
   Dim reader As SqlDataReader = sql.ExecuteReader()
   While reader.Read()
      Dim description As String = reader.GetString(0)
      ...
   End While 
Finally
   sql.Dispose()
End Try

Did you notice something missing? That's right, the connection object is nowhere to be seen! You only see what you care about: running the query and retrieving the results.

In this case, the ExecuteReader creates and opens the connection before calling the real ExecuteReader. Then, when I dispose off the SQL object (or close the reader), the connection gets closed automatically.

Both classes, SQL and StoredProcedure, are well documented in the downloadable help file (AMS.ADO.chm zipped), which I created based on the XML comments inside the code (with the NDoc tool).

Architecture

As I mentioned before, I created a separate set of these classes for the four main data providers available in .NET today. The classes are named the same (SQL and StoredProcedure) but they're distinguished by the namespace they belong to:

  • AMS.ADO.SqlClient
  • AMS.ADO.OleDb
  • AMS.ADO.Odbc
  • AMS.ADO.OracleClient

.NET 2.0

I initially wrote the code in C# 2.0 so that I could take advantage of generics. The idea was to have a single generic base class for all data providers since the code would be the same except for the type names. I named my class "Command" (inside the AMS.ADO namespace) and declared it like this:

public class Command<ConnectionClass, TransactionClass, CommandClass, 
         ParameterClass, ParameterCollectionClass, DataReaderClass, 
         DataAdapterClass> : ICommand
{
  ...
}

So now, the same class serves as base for all four data providers -- SQL Server, OLE DB, ODBC, and Oracle -- and additional providers (such as SQL Server CE) can easily be added in future. Generics rocks!

After I had written the code, I wanted to use something like a typedef that would allow me to define the corresponding classes for all providers in one line of code, sort of like this:

public typedef AMS.ADO.Command<SqlConnection, SqlTransaction, 
         SqlCommand, SqlParameter, SqlParameterCollection, 
         SqlDataReader, SqlDataAdapter> SQL;

Unfortunately, C# doesn't have a real typedef equivalent -- the using directive is not the same -- so I was forced to define each class explicitly, along with all the required constructors, since they're not inherited. In short, I had to do this:

public class SQL : AMS.ADO.Command<SqlConnection, SqlTransaction, 
               SqlCommand, SqlParameter, SqlParameterCollection, 
               SqlDataReader, SqlDataAdapter>
{
   public SQL()
   {
   }
    
   public SQL(string sql);
   {
     ...
   }
    
   public SQL(string sql, string connectionString)
   {
     ...
   }
   
   ...
}

It wasn't much of a problem, but it's a clear example of how the absence of a language feature can make a significant difference. (In retrospect, I could have written this in C++, but I'm too attached to C#.)

After I had written the code, I discovered Visual Studio 2005's cool new "View Class Diagram" feature (by right-clicking on the project), and decided to generate it for my classes. Here's what ClassDiagram.cd looks like:

As you can see, my ICommand interface derives from System.Data.IDbCommand. I simply added a couple of extra properties and methods that I thought would be nice to have. Other than that, the Command-derived classes look very much like their .NET counterparts, so they're easy to pick up.

.NET 1.1

After I had written and documented the code, I decided to generate the help file from the comments in the code. The only tool, I know of, that does it is NDoc, which as of this writing does not support generic types in .NET 2.0. I decided to shelve this project to see if a working version of NDoc would be released... but it never came. So, I finally decided to create a version of these classes for .NET 1.1. This would also allow those users who still haven't moved to .NET 2.0 to use these classes. Of course, the downside would be that I would have to create four new sets of classes, and duplicate the code in the Command class directly inside each one. Not a pretty sight, but it worked.

I created a separate Visual Studio .NET 2003 solution inside the NET 1.1 folder, where I copied the files into. I kept the same names across the board, for both classes and namespaces. The idea is that when you switch to .NET 2.0, you'll just need to reference the .NET 2.0 assembly and rebuild your project(s). No code changes will be required.

So the help file is based on the .NET 1.1 version, but it's applicable to both assemblies since the names are the same.

Testing

I tested my code using the popular NUnit tool -- csUnit was still not available for .NET 2.0.

I created a "Test" folder where I added "fixtures" for the SqlClient, OleDb, and Odbc classes. They all work with the local SQL Server database using Windows authentication, and automatically create a small database ("testAMSADO") along with a couple of tables and stored procedures.

Since the test source files depend on the nunit.framework assembly, I decided to exclude them from the solutions to eliminate the unnecessary dependency. The files are still there in case anyone's interested. Here's how I had it set up for the two assemblies:

  • The .NET 2.0 project built the test files right into the assembly, so I would load AMS.ADO.dll directly into NUnit.
  • The .NET 1.1 solution had a separate project (AMS.ADO.Test.csproj) for the test files inside the same Test folder, so I would load AMS.ADO.Test.dll into NUnit.

The tests were great in helping me verify that the code worked as designed. I highly recommend testing low-level code with tools like NUnit.

Usage

The downloadable zip file contains both the .NET 1.1 and 2.0 versions of AMS.ADO.dll (named the same, under different folders), so be sure to use the one appropriate for your project.

  1. Open your own project inside Visual Studio .NET.
  2. Inside the Solution Explorer toolbox, right-click on the References folder and select "Add Reference".
  3. Click on the Browse button and select the AMS.ADO.dll file. The .NET 1.1 version is inside the NET1.1 folder.
  4. Click OK. You may now use the AMS.ADO namespace inside your project.

If you want to minimize the size of the assembly (although it's only 24K), you can open the corresponding solution inside Visual Studio and exclude the source files that you don't need. For example, if you won't need Oracle or ODBC access, you can right-click on OracleClient.cs and Odbc.cs and select "Exclude From Project". Then, you can remove the reference to System.Data.OracleClient. As an alternative, you may wish to copy the individual .cs files to your own project to avoid adding yet another assembly to your distribution.

History

  • Version 1.0 - Dec 22, 2005
    • Initial release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alvaro Mendez
Web Developer
United States United States
Member
I've done extensive work with C++, MFC, COM, and ATL on the Windows side. On the Web side, I've worked with VB, ASP, JavaScript, and COM+. I've also been involved with server-side Java, which includes JSP, Servlets, and EJB, and more recently with ASP.NET/C#.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGood piece of code!memberPratik.Patel13 Jan '09 - 21:39 
Hi Alvaro,
This is a good code. I suspected that you might have opened the connection in constructor of the SQL but it is not written that way for the apparent cause. It is a good practice to open it only when we require it (Your Connect() method does that!)
 
You get 5 from me!
 
I have a query on the SQL Class:
public class SQL : AMS.ADO.Command<sqlconnection,>
{}
 
What does this statement mean? Does it mean that your command is of the type (SqlConnection, SqlTransaction, SqlCommand, SqlParameter, SqlParameterCollection, SqlDataReader, SqlDataAdapter).
 
Regards,
Pratik

QuestionTransactionsmemberjeanko28 May '07 - 3:00 
Hello,
 
can somebody help me how can I use ams.ado and sql transaction. I tried
 

Dim transaction As SqlClient.SqlTransaction = _
sql.Connection.BeginTransaction("test")
 
sql.CommandText = "Insert into ...."
sql.ExecuteNonQuery()
sql.Transaction.Commit()

 
But the exception raised on BeginTransaction with NullReferenceException.
 
By the way AMS.ADO is great work!
 

 
Honza Smrcka
AnswerTransactionsmemberpbnec5 Sep '08 - 17:03 
[I will use C#...]~
First, you may ADD A METHOD ON THE CLASS "AMS.ADO.Command" like~
		public void BeginTransaction()
		{
			m_command.Connection = new ConnectionClass();
			m_command.Connection.ConnectionString = m_connectionString;
			m_command.Connection.Open();
			m_command.Transaction = m_command.Connection.BeginTransaction();
			m_connectionString = null;
		}
Second, you may use the following code segment like~
		private void aMethod(object data)
		{
			//your before thing
			using (SQL sql = new SQL(string.Empty, connStr))
			{
				sql.BeginTransaction();
				try
				{
					//do your thing
					sql.Transaction.Commit();
				}
				catch (Exception ex)
				{
					sql.Transaction.Rollback();
				}
				finally
				{
					sql.Connection.Close();
				}
			}
			//your after thing
		}

GeneralConnect and dispose methodsmember_ra7 Jun '06 - 10:39 
here is my question:
how do you keep the connection around?
 
I have a stored procedure that gets called thousands of times in the loop. This causes the connection code in the Connect() method to open new connection and then the dispose gets called immediately after that.
 
In your code the "connect()" method only checks if the connection string is null, if it's not null then it opens new connection and then the dispose is called.
If I have to call my store procedure 20K times, that's how many times it will open and dispose the connection.
 
and ideas on how to fix that? work around?

 
_ra
GeneralRe: Connect and dispose methodsmemberAlvaro Mendez20 Jul '06 - 10:56 
_ra wrote:
how do you keep the connection around?

 
Pass in your own connection object to the constructor, instead of a connection string. If it's closed when you call Execute, it will be opened and closed automatically. If it's opened when you call Execute, it will be kept that way.
 
Regards,
Alvaro
 

The bible was written when people were even more stupid than they are today. Can you imagine that? - David Cross
GeneralRe: Connect and dispose methodsmemberPratik.Patel13 Jan '09 - 21:41 
Its never a good practice to call SP multiple times. See if you can prepare xml and pass it to the SP. It will give you excellent results. for more details you can refer OpenXML and WITH clause of MSSQL.
 
Regards,
Pratik

Generalright up my alleymemberjgaley24 Feb '06 - 9:17 
I can attest to the value of what you were saying about how your library is familiar to people who are used to ADO.NET. I just stumbled across your libary, and I was able to implement it right away in the project I am doing. I just commented out the old lines of code, duplicated the functionality using the SQLClient class, and the project works just the same. I cut back about half the lines of code.
 
I am looking at the Enterprise Libary Data Access Application Block, too, but the implementation does seem cumbersome to me, whereas yours is simpler and more familiar to me. I am planning on using your library It may just be a reflection of where I am as a programmer, but your implementation is right up my alley at this time. Thanks! Smile | :)
 
Jason
GeneralRe: right up my alleymemberAlvaro Mendez1 Mar '06 - 14:25 
Thanks Jason for your great review. It means a lot. Smile | :)
 
Regards,
Alvaro
 

To announce that there must be no criticism of the president, or that we are to stand by the president right or wrong, is not only unpatriotic and servile, but is morally treasonable to the American public. - Theodore Roosevelt
GeneralI am not able to read the documentmemberLai Song Tsair11 Jan '06 - 20:51 
When I open the AMS.ADO.Chm, i show "The page cannot be displayed", what should i need inorder to read tne document ?

GeneralRe: I am not able to read the documentmemberAlvaro Mendez12 Jan '06 - 5:35 
It works fine for me so I don't know what the problem could be. I did some googling on the problem and got a lot of hits[^].
 
Please let me know what you end up doing to solve the problem.
 
Thanks,
Alvaro
 


QuestionHelpmemberdkrsaturndev11 Jan '06 - 7:38 
Hello Alvaro,
 
I have converted your AMS.ADO to VB but having a problem that stumps me. I would like to email you the VS 2005 Project and see if you could see what the problem is.
 
I am getting the this same type error:
'Public ReadOnly Property Connection() As ConnectionClass' and 'Private Property Connection() As System.Data.IDbConnection' cannot overload each other because they differ only by 'ReadOnly' or 'WriteOnly'.
 
I am not a pro programmer so my use of interfaces and such is limited. If you could help I would be happy to email you the zip file being that I do not see a way to upload it here.
 
Thanks - Jeff

 
jsledge@dkrcapital.com
AnswerRe: HelpmemberAlvaro Mendez11 Jan '06 - 8:31 
I'll be happy to take a look. Email it to me at alvaromendez @ consultant . com. Be sure to include the details of the error you're getting.
 
Regards,
Alvaro
 


QuestionRe: HelpmemberGPilotino31 May '06 - 3:24 
I have the same "overloading" problem in VB. Any solution found ?
 
Many thanks,
Gino
NewsMS Enterprise LibrarymemberAkaitatsu11 Jan '06 - 2:40 
This is exactly the type of thing the Enterprise Library was created for. You might want to look into it. There is no sense in reinventing the wheel and the Enterprise Library was built using all the best practices prescribed by Microsoft. Best of all, it simplifies many stored procedure calls down to two lines of code.
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/entlib.asp[^]
 
Bryant
GeneralRe: MS Enterprise LibrarymemberAlvaro Mendez11 Jan '06 - 8:28 
Akaitatsu wrote:
This is exactly the type of thing the Enterprise Library was created for. You might want to look into it.

 
I did, some time after I had began writing my library. Their first version came with a single SqlHelper class with a bunch of static methods. Dead | X| And it was only available for SQL Server.
 
The latest version is more object oriented and multi-database friendly, but I still don't like the interface (ie, DBCommandWrapper dbCommandWrapper = db.GetStoredProcCommandWrapper(sql) Dead | X| ). My library uses the same familiar IDbCommand interface (of SqlCommand, OleDbCommand, etc.) that we've all used in ADO.NET.
 
Also, now you have to install a bunch of libraries and set up a config file. It just seems really cumbersome.
 
Akaitatsu wrote:
There is no sense in reinventing the wheel and the Enterprise Library was built using all the best practices prescribed by Microsoft.

 
I don't believe I've reinvented the wheel. I implemented it differently and, IMO, better.
 
Akaitatsu wrote:
Best of all, it simplifies many stored procedure calls down to two lines of code.

 
You need at least three -- one to create the database object, another to create the command object, and the last one to execute it. My library only needs two -- one to create the StoredProcedure object and another to run it.
 
Regards,
Alvaro
 


GeneralRe: MS Enterprise LibrarymemberAkaitatsu11 Jan '06 - 9:28 
I thought it would be cumbersome as well, until I tried it. It didn't take long to get used to it and having the database connection information in the configuration and encryptable is a big plus.
 
I use data sets a lot and I call the LoadDataSet directly from the Database object. Most, if not all, the Execute methods will take a stored procedure name as a parameter rather than a Command object.
 
I'm not going to quibble over one line of code though. If your tool works well for you then there isn't anything wrong with using it. There isn't any value in retro-fitting your data access code unless you really need a feature of the Enterprise Library or something anyway.
 
Later,
Bryant
GeneralconnectionStringmemberDaveSadler10 Jan '06 - 4:15 
In your examples, is this an actual connectionString or is it the name of a from the web.config?
GeneralRe: connectionStringmemberAlvaro Mendez10 Jan '06 - 10:35 
DaveSadler wrote:
In your examples, is this an actual connectionString or is it the name of a from the web.config?

 
It's an actual connectionString, hence the name. Smile | :)
 
It can easily be retrieved from the config file by doing something like this:
 
string connectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
 
Regards,
Alvaro
 


GeneralRe: connectionStringmemberDaveSadler11 Jan '06 - 3:05 
That's what i thought... I was just wondering if you had taken that repeated code and moved it into your class also. Might be a nice feature.
GeneralRe: connectionStringmemberAlvaro Mendez11 Jan '06 - 8:37 
DaveSadler wrote:
That's what i thought... I was just wondering if you had taken that repeated code and moved it into your class also. Might be a nice feature.

 
Well, what I've done in the past is create a Config class with a bunch of static methods, like this:
 
public class Config
{
  public static string ConnectionString
  {
     get 
     { 
       return System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
     }
  }
 
  ....
}
Then I use Config.ConnectionString everywhere I need it.
 
Actually, now that you mention it, it may prove convenient to add a static connectionString field that gets used when the default constructor is called. It's worth considering...
 
Thanks,
Alvaro
 


GeneralNo I Don'tprotectorMarc Clifton6 Jan '06 - 7:33 
That is, no I don't:
 
When you want to run a database query or stored procedure, you typically follow the same set of steps every time:
 
I've always scripted the xmlSQL (sometimes in xml!) and used a preprocessor that automates loading the parameters from data objects in a specified container. My latest work simply autogenerates the SQL as well, so I just tell it the operation I want to do and the data objects to operate on. Of course, there's a mapper between data objects and table-fields, which is where the real power lies.
 
Marc
 
Pensieve
 

-- modified at 13:34 Friday 6th January, 2006
GeneralRe: No I Don'tmemberPaul Brower6 Jan '06 - 8:12 
Yes ... what Marc said ... I second it ...
 

GeneralRe: No I Don'tmemberSuper Lloyd9 Jan '06 - 19:55 
What Paul said!!
Except Marc wrapper seems better than mine...
GeneralReally?memberAlvaro Mendez6 Jan '06 - 9:58 
So you don't use ADO.NET at all?
 
No matter how fancy you choose to wrap it, changes are that you still end up using a Connection and Command object to actually perform your queries. Am I wrong?
 
Alvaro
 


GeneralRe: Really?protectorMarc Clifton6 Jan '06 - 10:53 
Alvaro Mendez wrote:
No matter how fancy you choose to wrap it, changes are that you still end up using a Connection and Command object to actually perform your queries. Am I wrong?

 
Well yes, but their not scattered throughout the code. There's a single class in the data access layer that implements the interface to ADO.NET. So sure, I could use this class to interface to other db's, etc., but there's more involved than just that. DB's have different wildcards, tokens, etc., so the SQL has to be built specific to the db engine as well.
 
Marc
 
Pensieve

GeneralRe: Really?memberAlvaro Mendez6 Jan '06 - 11:34 
Marc Clifton wrote:
Well yes, but their not scattered throughout the code.

 
OK. But I'm sure there are plenty of applications out there (none of them written by you, of course Smile | :) ) where the data access code is scattered all other the place. The benefits of removing the connection management details from all that code could be great.
 
In fact, I've seen some of these code generators repeating the same connection management logic inside the methods they generate. Dead | X|
 
Marc Clifton wrote:
So sure, I could use this class to interface to other db's, etc.,

 
Exactly, and instead of repeating the same 10+ lines of code (inside your Data Access layer or wherever) every time you run a query, you could use my class and cut that by as much as 50%.
 
Marc Clifton wrote:
but there's more involved than just that. DB's have different wildcards, tokens, etc., so the SQL has to be built specific to the db engine as well.

 
Right, and you would still do all of that the same way with my classes. Pick the SQL/StoredProcedure pair for your specific db engine and use it like you would a regular IDbCommand class.

Regards,
Alvaro
 


GeneralRe: Really?protectorMarc Clifton6 Jan '06 - 12:06 
Alvaro Mendez wrote:
But I'm sure there are plenty of applications out there

 
Well, yes. Of course. I guess I wanted stick my foot in it and say, well, I don't. Poke tongue | ;-P
 
Marc
 
Pensieve

GeneralRe: Really?membercomputerguru923821 Mar '06 - 14:46 
Marc Clifton wrote:
not scattered throughout the code

 
Smile | :)
GeneralRe: No I Don'tmemberrudy.net10 Jan '06 - 16:41 
Marc,
Can you share a link on the following two subjects that you mentioned?
 
Marc Clifton wrote:
used a preprocessor that automates loading the parameters from data objects in a specified container

 
Marc Clifton wrote:
My latest work simply autogenerates the SQL as well

 
Thanks,
Rudy.
GeneralRe: No I Don'tprotectorMarc Clifton11 Jan '06 - 1:01 
rudy.net wrote:
Can you share a link on the following two subjects that you mentioned?

 
I hope to eventually work up to that point with the "Diary of a CEO" series I'm co-authoring with Tony Lewis, though we have to figure out what can be released in the public domain and what is proprietary. Also, the implementation we're using is integrated, if that's the right word rather than "entangled", with our entire architecture. It may be better to introduce these concepts while staying on more comfortable footing for people, using typical DataSet and DataTable classes rather than containers, data objects, and specialized table classes.
 
So, hopefully some time soon!
 
Marc
 
Pensieve

GeneralRe: No I Don'tmemberTom Wright28 Aug '07 - 8:02 
Marc,
So in your DAL are you just defining these steps (see below) and passing it the connection string, the query and returning a dataset that fills in a grid view....of sorts?
 
How are you guys doing your app when you have more than one table that you have to access in an app...I don't want to create a connection schema like that listed below for each table that I need to pull data from and I'm not fully understanding (visually) how I create my DAL. I feel that I can create a class passing the connection string when I instanciate it and pass the query returning a dataset...right?
 
Create a command object and pass it the SQL for the query as well as a database connection object.
If it's a stored procedure, set the CommandType to StoredProcedure.
Set any parameters required for the query.
Open the connection to the database.
Execute the query and retrieve the records, if necessary.
Close the database connection.

 
Tom Wright
tawright915@gmail.com

GeneralRe: No I Don'tprotectorMarc Clifton28 Aug '07 - 8:10 
So, given that my post is 1.5 years old, at this point:
 
I use an XML schema to define tables and their relationships
I create virtualized views (not SQL views) of the tables I want for the CRUD operation
The middleware layer generates the correct SQL for the CRUD operation
Let's say it's a query--it gets sent down to the client (a thin client, basically)
The client runs a workflow (XML) that determines how the data is bound to the UI, basically, grids, individual controls, etc.
 
Marc
 

GeneralRe: No I Don'tmemberTom Wright28 Aug '07 - 8:19 
Well being that you are so wise in the ways of the programming world....I figured you would be the best person to ask (yes this is sucking up at it's finest).
 
Thanks for the quick response.....by the way is there an example of how you are doing your DAL with XML?
 
Thanks again
 
Tom Wright
tawright915@gmail.com

GeneralRe: No I Don'tprotectorMarc Clifton28 Aug '07 - 8:28 
Tom Wright wrote:
yes this is sucking up at it's finest).

 
Laugh | :laugh:
 
Tom Wright wrote:
by the way is there an example of how you are doing your DAL with XML?

 
Unfortunately not. It's actually the core of the Interacx server (see sig) and because I spent a lot of time figuring things out, it's proprietary. However, a lot of the rest of the technology, like data transactions and sandboxing, exists as articles on CP -- see the references[^] at the bottom of the link.
 
Marc
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 6 Jan 2006
Article Copyright 2006 by Alvaro Mendez
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid