Issue dated - 19th May 2003

-


Previous Issues

CURRENT ISSUE
INDIA NEWS
NEWS ANALYSIS
STOCK FILE
INDIA TRENDS
E-BUSINESS
OPINION
FOCUS
COMPANY WATCH
TECHSPACE
TECHNOLOGY
PRODUCTS
EVENTS
COLUMNS
TECH FORUM

THE C# COLUMN

BETWEEN THE BYTES
TECHNOLOGY
SPECIALS <NEW>
HMA BANKBIZ
EC SERVICES
ARCHIVES/SEARCH
IT APPOINTMENTS
WRITE TO US
SUBSCRIBE/RENEW
CUSTOMER SERVICE
ADVERTISE
ABOUT US

 Network Sites
  IT People
  Network Magazine
  Business Traveller
  Exp. Hotelier & Caterer
  Exp. Travel & Tourism
  Exp. Backwaters
  Exp. Pharma Pulse
  Exp. Healthcare Mgmt.
  Express Textile
 Group Sites
  ExpressIndia
  Indian Express
  Financial Express

 
Front Page > TechSpace > Story Print this Page|  Email this page

Reflections on the .NET framework — II

Tech Forum - Dr. Nitin Paranjpe

Object Role Connection Manage connection with a data source. Connection can be used by other objects to retrieve and update data. Dataset The container that holds the data returned from a datasource. Dataset does NOT know where the data came from. Data Adapter A conduit between connection and dataset. Dataset is filled with data coming from a data source using a connection. Similarly, data changed in dataset is updated using the data adapter. Data Reader A one-way (forward only) cursor that allows returning rows/results to be read and acted upon. Data reader does not provide for update of the resulting rows. It is purely READ-ONLY.

In the last article, I put forward a different way of learning new technology. The aim is to make the learning more real-life-oriented, more expansive and more effective. As an example of this new method of learning, I had suggested that we choose one simple, yet commonly used object from .NET and explore it. We chose the SqlConnection object from the System.data.sqlclient namespace. This represents the connection object for ADO.NET. As you know ADO.NET offers SQLCLIENT and OLEDB as two different implementations. SQLCLIENT is to be used only with SQL Server. OLEDB is to be used with all other data providers that do not have their specific implementation like SQLCLIENT. Nowadays, Oracle, Sybase and many other RDBMS vendors have released their custom implementations of the SYSTEM.DATA related objects.

While exploring the SqlConnection object, we will need to consider many peripheral topics. These topics would usually be assumed to be known to the learner. But often, this is not the case. Most technical books conveniently assume that the reader knows the larger picture and other links and therefore, don’t even mention the need to brush up these topics.

What does SqlConnection do?

Here I am assuming some background knowledge of ADO.NET. The SqlConnection object is simply the good old CONNECTION object of ADO, with much more functionality. The syntax is:

Dim conn as New SqlConnection()

Key differences

Now in order to utilise ADO.NET effectively, we need to understand one thing very clearly. The earlier implementation of data access using ADO and the current implementation of ADO.NET are radically different. You cannot learn ADO.NET by just finding out equivalent commands from the ADO era.

Therefore you need to know exactly what has changed in ADO.NET. This information is available in MSDN and various other sources. Here are the most important differences:

1. ADO required you to work on tables/views by creating a recordset. Multiple tables required multiple recordsets. There was no default linkage between multiple recordsets. In ADO.NET there is a container called Dataset, which can contain multiple tables (equivalent of recordset of ADO), relations, views and so on.

2. In ADO.NET the data manipulation in Dataset is always offline.

3. Therefore, there is no way of creating a DYNAMIC CURSOR

4. Forward Read Only cursor is available as a separate object called DataReader.

5. ADO.NET has different objects for performing different data management tasks. These cannot be interchanged. The objects along with their roles are described in the adjoining table.

6. The only ways to change data in a source are either by passing direct SQL Commands (including stored procedures) or through the dataset-data adapter combination.

Object Role
Connection Manage connection with a data source. Connection can be used by other objects to retrieve and update data.
Dataset The container that holds the data returned from a datasource. Dataset does NOT know where the data came from.
Data Adapter A conduit between connection and dataset. Dataset is filled with data coming from a data source using a connection.
  Similarly, data changed in dataset is updated using the data adapter.
Data Reader A one-way (forward only) cursor that allows returning rows/results to be read and acted upon. Data reader does not provide for update of the resulting rows. It is purely READ-ONLY.

What has not changed?

It is now important to know another aspect that is often left unsaid. Get this very clear: SQL Server 2000 has not changed after the launch of .NET. Only the way of accessing and manipulating data in SQL Server has been refined and made more object-oriented by providing a richer object model of ADO.NET. You might be wondering what’s so great about this. It is not so simple. Most of us tend to get carried away by new technology and forget the baseline stuff. For example, once you explicitly know that SQL Server is still the same, that can lead to many practical conclusions and best practices. For example:

1. For hard-core data crunching, SQL Server is still the preferred choice.

2. If you can achieve a task in ADO.NET with less code than ADO, that does NOT mean it is the best way of doing it.

3. You must analyse every data-handling task and ask yourself a question: Will SQL Server be better at doing this or will ADO.NET do a more efficient job? The answer will depend upon circumstances.

4. SQL Server performance depends upon how often it has to keep connections alive and how many requests are received. Therefore, the age-old dictum of minimising connection time, minimising transaction time and minimising locks still holds true.

5. ADO.NET will appear to provide all the functionality that the SQL data engine itself provides. Examples are constraints, primary foreign key relationships, views, events that are like triggers and so on. You have to use an extreme amount of discretion to decide which is the right place to do what.

Examples of possible misuse of ADO.Net

  • Using events instead of triggers

    It is very tempting to use the RowChanged event to write code instead of writing it in the good old update trigger! Unfortunately, when to use or not use the RowChanged event is not mentioned anywhere. You have to think about it actively.

  • Using dataset level code instead of stored procedures

    Datasets give row-based data handling. SQL syntax provides set-based data handling. Dataset-based handling of data is happening away from the SQL engine in an offline manner. Stored procedures run in the heart of the SQL engine. If you need to refer to other tables and perform updates across data items, it is best managed using stored procedures. Dataset-level data manipulation should be limited to the entities available in the runtime environment, away from data engine(s). Sounds like common sense but I have seen this mistake being repeated too often at too many clients while performing code audits.

Positioning of the SqlConnection object

With the above information, we can now understand the SqlConnection object. SqlConnection is the connection ONLY for SQL Server 7 or above (SQL 2000 is preferred).

The next logical question is: Can we use OledbConnection object for SQL Server data access? The answer is YES. But it is not recommended because this is guaranteed to be less efficient and slower than using SqlConnection. This is because SqlConnection is explicitly written to provide the best performance with SQL Server. It uses all possible techniques to enhance data access and also exposes all possible sophisticated features of SQL Server.

Intellisense: Method overrides

As soon as you try to type the define the object, you will see the tooltip and ‘intellisense’ which explains the syntax of the SqlConnection.

Tooltips were originally invented to explain what a toolbar button meant because there were too many buttons! Now they are a part of IDE intellisense also. The confusing part is the tooltips are so long that they have scrolling text. In case of methods, they scroll to show you different ways in which the method can be called—to show overridden method calls. We generally tend to ignore this. These tooltips capture the up-down arrow keys and scroll within them. This is irritating when you want to move to the next or previous row. But anyway, they are here to stay. The important part is the overrides. In case of SqlConnection there are only two of them (fortunately!). One without any parameters and one with the connection string parameter.

Most of us will find it very simple to understand that you can either pass or not pass the connection information. We will then move on to write the next line of code. That is how new technology is learnt. It is too intuitive to understand these two variants of SqlConnection initialiser and then move on. We know the connection string for this dev machine so we will put it in and go ahead. We have also convinced ourselves that we have understood the SqlConnection initialisation syntax. I call this the "Hello World" approach. But we have to apply a different approach. So here’s the twist:

‘Hello, REAL world’ approach

Don’t just move on and think you have understood the syntax. Why? Because we just lost an opportunity to apply this knowledge to a real-life production scenario.

Let us try and think of real life. From a production environment point of view, the following questions arise:

1. Which type of syntax to use in real life?

2. While coding we can hard-code these connection strings. But what next?

3. While deploying the application, how are we going to include the production database connection info? Who will input the details? How? Does the setup provide for this?

4. What happens if the backend database changes to another machine or another user is required for the logon?

5. Are we going to use integrated security or SQL Server security? Which one is more suitable for the customer?

6. Is this connection being called form a component or from a UI (winform/webform)? If it is being called from a UI, which userid should be used? If the logged-on user credentials are used, how to prevent misuse?

7. In a production environment, the password should not be visible. How are we going to achieve this? Integrated security takes care of this because password need not be a part of the connection string. But what about SQL Server level security? Where will you put the password and hide it?

8. If the password is in the config file, it is still exposed. Should we use the cryptography API to encrypt the connection string and then decrypt it at runtime before passing it as a parameter to the SqlConnection object?

9. What happens if the user password changes at SQL Server level? How are we going to re-encrypt the new password into the config file?

10. If this is a component, would it not be better to use the functionality of component constructor where a parameter can be configured in MTS itself, without having to change the code at all and without a config file?

While thinking of all this, you will finally conclude—why not just use the DSN funda? It was the way we handled connection properties in past. Now you are in for a rude shock. DSNs are not supported in ADO.NET!

When you consider various options that the above questions lead to, you will finally reach the following conclusion: In most cases, it is best to pass the connection string as a constructor to a component in MTS. Now, believe me, this is not written in any reference material with so much clarity and justification. In fact, the constructor functionality has been there in MTS for years. But we have never used it effectively in all possible circumstances. From this, another piece of knowledge emerges:

Nothing has changed in MTS functionality. We need to make use of all the features like pooling, transaction management and so on using native MTS functionality that is exposed by Enterprise Services.

Have you used MTS with COM components in past projects (before .NET)? If the answer is yes, then ask yourself whether you have used MTS just as a setup and installation utility or have you used other features of MTS as well. Now, you know you are in a slippery territory. Believe me, in spite of COM and MTS being in the market for so many years, I am yet to see proper utilisation of all relevant features of MTS in an application.

The baseline features that should have been used are:

1. Deployment and management packages containing related components.

2. Security at the method level, which can be role based.

3. Transaction management.

4. Object pooling.

5. Events.

It is very rare for a custom-built application (whether in-house or packaged product or application service provider apps) to use all these features effectively. Why so? Is it too cumbersome to use these features? Or is it unnecessary to use all these features? Or you can get maximum benefits just by using the deployment features?

The answer is ‘none of the above’. It is indeed very rare that a team of architects, developers and application designers have actually changed their mindset of writing components to take advantage of MTS. If you ask any techie to describe (in English) how should you write components for MTS, you will only get silence as the answer.

MTS allows developers to write components as though these were being written for a single-user, idealistic scenario. All the complexity of transaction management, security, deployment, and performance is managed by MTS—outside the code.

If you have not understood this till now, please do so NOW. This can revolutionise your IT career! Now, extrapolating from the above knowledge, other great functionality becomes apparent:

If you have independent components which utilise all relevant features of MTS, you can assemble these components in any logical execution order—even at run-time—without worrying about transaction management, security, performance and appropriate invocation. This is the real beauty of the MTS functionality.

Now how is all this related to SqlConnection command? This thought process started when we wanted to decide whether to provide the connection string to the SqlConnection object while instantiating it or whether to pass it from somewhere outside. Now, considering that all business components are going to reside in MTS, it makes tremendous sense to finalise the following guideline.

For all components, the connectionstring should be stored in the constructor rather than keeping it in config files or passing it as an ad hoc parameter.

On the other hand, if the application is never going to use components as such, config file is the right approach.

Now we have done justice to the two variants of instantiating SqlConnection object! Do you see what I mean by a different method of learning? Do you perceive the broadening of your knowledge and understanding of the subject by thinking beyond syntax? I will continue exploring this SqlConnection object (and more importantly, highlighting this new method of learning) next week. In the meanwhile, do give me feedback about this learning experience. I will be glad to incorporate your feedback and refine my content for everyone’s benefit.

About the Author:Dr Nitin Paranjape is the Chairman and MD of Maestros (Mediline). He is a consultant with many organisations, covering appropriate technology utilisation, business application of relevant technology, application architecture and audit as well as knowledge transfer. He has authored more than 650 articles on various technology-related subjects. He can be contacted at nitin@mediline.co.in
<Back to top>


© Copyright 2003: Indian Express Group (Mumbai, India). All rights reserved throughout the world. This entire site is compiled in
Mumbai by The Business Publications Division of the Indian Express Group of Newspapers.
Please contact our Webmaster for any queries on this site.