.NET Performance Blog

August 9, 2006

ENTechSolutions.com launched, XLib is available for download

Filed under: .NET,General,XLib Framework — Eric P @ 1:51 pm

I finally launched a web site for my consulting company:

http://www.entechsolutions.com

At the same time I packaged BETA versions of XLib and XWebSiteTemplate.  You can find these products as well as AutoSuggestBox control in the ‘Developer Corner’ section of the web site.

Advertisements

July 18, 2006

AJAX Modal Dialog using UpdatePanel

Filed under: .NET,XLib Framework — Eric P @ 5:57 pm

Please see complete post here:

http://www.entechsolutions.com/Blog/ViewPost.aspx?PostID=6

April 10, 2006

Connection/Transaction scope

Filed under: XLib Framework — Eric P @ 12:57 pm

I have been doing some research on already available classes for keeping track of open transactions and connections. For .NET 2.0 Microsoft has released TransactionScope class which really simplifies keeping track of simple, nested and distributed transactions. It is very simple to use and MSDN documentation is pretty good. The only issue I found was that if you keep re-creating connection inside a transaction – the final transaction would be distributed which may result in performance loss.

Luckily one of the members of ADO.NET has countered the problem here:

http://blogs.msdn.com/dataaccess/archive/2006/02/14/532026.aspx

His class DbConnectionScope keeps track of already open connections and re-uses them within a TransactionScope. Following his lead I came up with two classes:

  • XOpenCnScope
  • XOpenCnTransScope (derived from XOpenCnScope)

These two classes allow me to open connection or connection & transaction scope using one statement. Internally open DbConnection and TransactionScope are re-used until all the nested Scopes have been closed.

Here is an example of open connection with transaction:

using (XOpenCnTransScope scope1 = new XOpenCnTransScope())

{

InsertRecord(1001);
InsertRecord(1002);

scope1.Complete();

}

public void InsertRecord(int recID)

{

XCommand cmd = new XCommand();

string sql = "INSERT INTO Db.Sample_XOpenCnTransScope (ID, Name) VALUES (" + customerID + ", '" + "Name_" + recID + " ')";

cmd.ExecuteSql(sql);

}
XCommand object is aware of XOpenCnScope and XOpenCnTransScope (similar of how TransactionScope is aware of DbConnection.Open). So when XCommand executes a query it will use the connection with transaction provided by OpenCnTransScope.

Actually if you create a new XCommand outside of OpenCnScope – it will automatically open default application connection – execute the query and close connection. That saves 4-5 lines of code.

April 6, 2006

Database Access Layer

Filed under: XLib Framework — Eric P @ 3:21 pm

Using XLib framework I would like to build web applications consisting of the following Tiers:

Database Access

Business Logic

Presentation

In this post I will talk about Database Access layer of XLib. There are a couple of things that I tried to accomplish:

  1. Automatically convert Database values into INullable datatypes. Handle DBNull.
  2. Hide complexities of DataSet, DataAdapter, etc…
  3. Build queries using OOP

Dilemmas I had to face:

1. Should I use Typed DataSet for Data Access?

I have tried the new DAL generation tools in VS 2005. It is very quick to generate a DAL over one database table. It also automatically converts DB data types into INullables. But there were a couple of issues that I could not figure out how to do:

  • The <<Item>>Row object (ex. CustomerRow) doesn't use Nullable types for properties. So how do I set CustomerRow.Age to null? Before I would use a NIL constant (like -1), but with INullables I would rather not use that. The weird part is that .Insert() and .Update() methods of CustomerTableAdapter take INullable types.
  • Generator creates 3 classes: Customer, CustomerRow & CustomerTableAdapter. It makes it a little more complex than it needs to be.
  • If I want to load some lookup values (for example CustomerType Lookup name) and use inner join in query to generate typed DataSet — the generator would not automatically create UPDATE, INSERT, DELETE. It only works if data is loaded from one table. I could always add GetCustomerTypeName() method to Customer partial class, but I would like to be able to load all info using one query.

For now I will fore-go TypedDataSet, but it is a lot better then in .NET version 1.1.

2. Should I use ANSI convention or SQL-86 (tables are separated from joins) for query building.

I have been using SQL-86 for most of my query writing and used ANSI whenever OUTER JOINS would get too complex. At this point I would like to start using ANSI for most of the new queires. One reason is Microsoft seems to be trying to phase SQL-86 out. The other is that queries are a little cleaner in ANSI format.

For now, I have decided to support both formats .

3. For transaction handling should I use TransactionScope?

This one I researched for a while. The implementation is very straight forward. The main thing I looked at was Nested transactions. The only issue is – possible overhead of using distributed transactions. For example:

void Foo1()

{

using {TransactionScope ts1=new TransactionScope();}

{

using (SqlConnection cn1=new SqlConnection)

{

cn1.Open();
//Do some functionality
foo2();

}

ts1.Complete();

}

}

void Foo2()

{

using {TransactionScope ts2=new TransactionScope();}

{

using (SqlConnection cn2=new SqlConnection)

{

cn2.Open();
//Do some functionality

}

ts2.Complete();

}

}

Does it create a distributed transaction with ts1 and ts2? How much overhead is there? Would it be more efficient if I re-use open transaction and open connection instead of just re-creating them? I will need to run some tests.

Also how does it work internally? In the sample code Connection is disposed off before TransactionScope is disposed. How is it possible to commit transaction after connection is closed. TransactionScope probably keeps track of all the opened connections and doesn't let them close till transaction is completed.

I still need to do some more testing to see if I need to switch or not.

4. How much of DbCommand, DataAdapter, etc… functionality to hide?

Let's take a look at executing a sql statement using SqlCommand

using (SqlConnection connection1 = new SqlConnection(connectString1))
{
connection1.Open();

// Create the SqlCommand object and execute the first command.
SqlCommand command1 = new SqlCommand(commandText1, connection1);
returnValue = command1.ExecuteNonQuery();
}

In my code under any DataObject I would use the following:

XConnection cn=new XConnection();

cn.GetCmd().ExecuteSql(commandText1);

XConnection automatically load ConnectionString from config file. It can be overriden through a property.

GetCmd() returns XCommand object which provides common Sql methods: ExecuteSql, QueryLookupInt, LoadListStr, etc…

ExecuteSql method will generate the command and automatically open and close connection.
This is still a big question for me. Many of these functions I have written before .NET 2, so I still need to see what is available.

Here is the final list of XLib Db classes.

XLib.db Classes

  • XConnection
  1. Provides generic access to Sql Server, Access, Oracle, etc…
  2. Handle transaction start/end/commit
  • XDataObject
  1. Exposes connection object
  2. Implements nested transaction scope. So I re-use a transaction if it already exists
  3. Implements nested connection opens scope. So I re-use open connection if it is already open.
  • XDataReader
  1. Automatically convert db values into INullable data types.
  2. Internally use .NET DataReader.
  3. Efficient paging (use PAGE_INDEX() in Sql Server
  • XDataWriter
  1. Automatically convert INullable data into db values. Handle DBNull.
  2. Internally use DataSet and DataRow
  3. Can insert, update, delete data in one table
  4. Generate INSERT, UPDATE, DELETE statements dynamically. Don't use SqlCommandBuilder, since it is a huge hit to performance.
  • XQuerybuilder
  1. Allow for ANSI or SQL-86 notation.
  2. Parse text representing SQL query into the object
  • XDataRecordReadOnly
  1. Abstract class with Load method
  2. Uses XDataReader to read data from one table
  • XDataRecord
  1. Derived from XDataRecordReadOnly
  2. Abstract class with Save, Delete methods
  3. Uses XDataWriter to write/delete data to one table

April 5, 2006

Foundation for the New Framework

Filed under: XLib Framework — Eric P @ 10:54 am

A project can only be as good as its foundation. If a house foundation is shaky, it doesn't matter how great the design is above ground. At every step, builders will have to deal with issues created by bad foundation.

Microsoft recently came with an excellent attempt at a foundation – .NET 2.0 and VS 2005. It tries to do everything, and succeeds in most cases. By writing a framework on top of .NET 2.0 I will try to fill the gaps in the specific area that I spend most of my development time: N-tier web applications.

My RAD framework is based on .NET 2.0 and Sql Server 2005. When I am finished I will make the framework open to the public, because I think that's the best way to improve it quickly.

The framework will consist of three major pieces:

XLib — base API for DataAccess, IO Access, Business Logic, etc…

XCodeGenerator — for generating classes and web pages from database tables

XWebSiteTemplate — generic modules for building the sites:

* User Manager

* Content Manager

* Email Manager

* …

Right now I am half of the way through the XLib, so there is plenty of work to do.

Blog at WordPress.com.