Falling in love with a ghost :D

After a long time that some friends told me about boo language, finally yesterday I downloaded the trunk and began to familiarize with the language. The first thing that surprised me is the ability to break into debugger with simple instruction like these

import System.Diagnostics

Debug.Fail(“”)

And your favorite debugger will show up with full support for intellisense, step and so on, I’m very pleased with this.

Alk.

Overhead calling UDF in Sql server 2005

Today I found a performance issue in a project of mine, after some try, I found that the overhead of calling a udf function is really enormous…I have a query that move data from a table to another, it move about 25.000 rows, and one of the field of original table is transformed with a UDF. The query without udf runs in about 1500 ms, the query that calls udf runs in 180 minutes, even if in the UDF I simply return the parameter and do no calculation at all. Then I come across this post that deals about this issues…..so the rule is, do not use udf if you know that the udf will be called for thousands rows.

Alk.

The hell of disabling viewstate in asp.net 2.0

The application model of Web Forms is not the most intuitive one, but to avoid being surprised and loosing time the most important thing to keep in mind is page lifecycle. If you forget page lifecycle hell awaits you. Here is one of the most common example, look at the following code.

<body>
    <form id=”form1″ runat=”server”>
        <div>
            <asp:DropDownList ID=”MyDDListe1″ EnableViewState=”true” AutoPostBack=”true” AppendDataBoundItems=”true”
                runat=”server” OnSelectedIndexChanged=”SelectedIndexChanged”>
                <asp:ListItem>Select a team</asp:ListItem>
            </asp:DropDownList>
        </div>
    </form>
</
body>
</
html>

<script runat=”server”>
    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            MyDDListe1.DataSource = new string[] { “Ferrari”, “McLaren”, “Renault” };
            DataBind();
        }
    }
    protected void SelectedIndexChanged(object sender, EventArgs e) {
        string msg = string.Format(@”alert(‘Selected item {0}’);”, MyDDListe1.SelectedValue);
        ClientScript.RegisterStartupScript(GetType(), “blah”, msg, true);
    } 
</script>

It is a very simple one, a simple page with a single dropdownlist, when you select a different item in the ddlist, a messageBox appears showing the selected element. All works fine until you choose to disable viewstate, mainly for performance reason and for page size reduction. When you set EnableViewState property of the DDL to false, the example ceases to work. When you choose a team the message box does not show selected team, and all the items in the DDL disappear. First thing to do is remove the check if (!IsPostBack) made in form Load event, now all content of the DDL must be reloaded at every postback because there is no viewstate anymore to restore the old values. Now the DDL retains all elements, but the messagebox continues to miss the selected item. Now you should resist the temptation to open google to find the solution, and instead you should really ask yourself “why the combo does not retain the selected value in SelectedIndexChanged event?”. The answer is in page lifecycle; every control has an event called LoadPostData() that is called from infrastructure to make control restore its current value from post data. The AspNet infrastructure calls LoadPostData() in a time between page init and page load, so if you disable the viewstate and reload DropDownList elements in page load, when the page controller calls LoadPostData the DropDownList tries to recover selected values from post but it has no items yet, and so nothing gets selected. To solve the problem you must bind the ddl in page Init.

To verify that this is really the reason you can do a simple test, first of all create a new control that inherits from the dropdownlist and exposes a method that internally calls protected method LoadPostData().

[DefaultProperty(“Text”)]
[
ToolboxData(“<{0}:MyDDListe runat=server></{0}:MyDDListe>”)]
public class MyDDListe : DropDownList  {
 
   
public void reloadValueFromPost() {
      
this.LoadPostData(this.ClientID, HttpContext.Current.Request.Form);
   }
}

As you can see the LoadPostData() method accepts the key of the data in the post (the control id contained in ClientId property) and the collection of post parameters. With this control at hand change the page in this way

<body>
    <form id=”form1″ runat=”server”>
        <div>
            <cc1:MyDDListe ID=”MyDDListe1″ EnableViewState=”false” AutoPostBack=”true” AppendDataBoundItems=”true”
                runat=”server” OnSelectedIndexChanged=”SelectedIndexChanged”>
                <asp:ListItem>Select a team</asp:ListItem>
            </cc1:MyDDListe>
        </div>
    </form>
</
body>
</
html>
<
script runat=”server”>
    protected void Page_Load(object sender, EventArgs e) {
        MyDDListe1.DataSource = new string[] { “Ferrari”, “McLaren”, “Renault” };
        DataBind();
        MyDDListe1.reloadValueFromPost();
    }
    protected void SelectedIndexChanged(object sender, EventArgs e) {
        string msg = string.Format(@”alert(‘Selected item {0}’);”, MyDDListe1.SelectedValue);
        ClientScript.RegisterStartupScript(GetType(), “blah”, msg, true);
    } 
</script>

As you can see the DropDownList now gets substituted by MyDDListe control, in page load I simply calls reloadValueFromPost() method, this make my ddl to calls again LoadPostData() of the base control, and the example now works again, even if the data binding is done in Page Load event. When the viewstate is enabled the viewstate is restored before LoadPostData() gets called and all works as expected.

So, every time a WebForm seems to behave in a strange way first of all think about page lifecycle, and most of the time you’ll find the answer.

Alk.

P.S another way to verify this issue without the need to create a new control just to be able to call LoadPostData() that is a protected method, remember that through reflection calling a protected method is a breeze. The following code makes the combo work even if databinding is done in page load, clearly the best thing to do is rebind the combo in page init, but the following code is a verification that the reason why the combo stops to work with viewstate disabled is really the fact that LoadPostData() is called before page load.

protected void Page_Load(object sender, EventArgs e) {
    MyDDListe1.DataSource = new string[] { “Ferrari”, “McLaren”, “Renault” };
    DataBind();
    MyDDListe1.GetType().GetMethod(“LoadPostData”, System.Reflection.BindingFlags.NonPublic
        | System.Reflection.BindingFlags.Instance).Invoke(MyDDListe1,
        new object[] { MyDDListe1.UniqueID, Request.Form }); 
}

C# anonymous delegates and template pattern

Yesterday I blogged on a slightly modified version of Ayende code posted here, this makes me reflect on template pattern of the GOF. Template pattern is one of the most useful pattern, and is used when you have a common block of code that is to be repeated in may part with a little customization. In the GOF the intent of the pattern is

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

The original description of the pattern explicitly states that the implementation is made by a template class (usually abstract) and then a series of subclasses, each for a different variation of the algorithm that is to be implemented. C# anonymous delegates are a great way to implement a template pattern even with a static class, without the need to use subclasses or inheritance. The post from Ayende is a great example of this. In his code Ayende creates a base method that accepts a delegate with all the common infrastructure to execute ad Ado.NET DbCommand. In the base static function he creates connection, starts a transaction and creates a command that will be attached to an open connection, then he calls the delegates passed as an argument. With anonymous delegate the caller is able to specify a block of code that logically will be substituted into the inner part of the Template static method. This kind of implementation can also be done in C++ with function pointer, but is definitively not so readable as counterpart in C#.

Alk.

An helper class to access databases with ado.

A while ago I read an exceptional post by Ayende, I found it very interesting, and I decided to use his technique with some projects, but I choose to do a little modification to make the code works with every type of database, not only with SqlServer. Here is my version. All real code is made by ayende, I simply do some changes to make it database agnostic.

public static void Execute(VoidFunc<DbCommand, DbProviderFactory> functionToExecute) {
   
DbProviderFactory factory = DbProviderFactories.GetFactory(
      MainConnectionString.ProviderName);
   
using (DbConnection connection = factory.CreateConnection()) {
      connection.ConnectionString = MainConnectionString.ConnectionString;
      connection.Open();
      
DbTransaction tx = connection.BeginTransaction();
      
try {
         
using (DbCommand command = factory.CreateCommand()) {
            command.Connection = connection;
            command.Transaction = tx;
            functionToExecute(command, factory);
         }
         tx.Commit();
      }
      
catch {
         tx.Rollback();
         
throw;
      }
      
finally {
         tx.Dispose();
      }
   }
}

The modification from the original ayende’s code is the following: instead to directly create a SqlConnection I use DbProviderFactories to create a DbProviderFactory, with this object I can create connection and parameter based on the provider name specified in the app config. The connectionstring is taken from a property MainConnectionString that simply use ConfigurationManager to get the connection from the app.config, this property returns a ConnectionStringSettings object that not only stores the effective connection string, but contains also some other properties, such as ProviderName, used to specify the provider. The rest of the code is the same of exceptional Ayende’s example. The delegate I use to execute the query accepts both a DbCommand and a DbProviderFactory that must be used to create parameter for the command. I also inserted another helper function that adds a parameter to the command choosing the right name at runtime based on the provider type (this is necessary because for Oracle parameter names are to be prefixed with :, sql server use @, etc…).

private static Dictionary<Type, String> mParametersFormat = new Dictionary<Type, String>();
 
private static String GetParameterFormat(DbCommand command) {
   
if (!mParametersFormat.ContainsKey(command.GetType())) {
      mParametersFormat.Add(
         command.GetType(),
         command.Connection.GetSchema(
“DataSourceInformation”)
            .Rows[0][
“ParameterMarkerFormat”].ToString());
   }
   
return mParametersFormat[command.GetType()];
}

public
 static void AddParameterToCommand(
   
DbCommand command,
   
DbProviderFactory factory,
   System.Data.
DbType type,
   
String name,
   
object value) {
 
   
DbParameter param = factory.CreateParameter();
   param.DbType = type;
   param.ParameterName = 
String.Format(GetParameterFormat(command), name);
   param.Value = value;
   command.Parameters.Add(param);
}

As you can see I store the format of the parameter in a dictionary indexed by command type. For each different type of commands (SqlCommand, OleDbCommand) I store the ParameterMarkerFormat string that is retrieved with DbConnection.GetSchema() function. This caching could be avoided if we are sure to use the same db in every part of the application (an assumption that is easily true since it is very strange to create an application that stores some data in a sql server and some other data in a different engine, for example Oracle). The ParameterMarkerFormat is a sting that can be used with String.Format to create the right parameter name for the current provider, for example with sql server is “{0}”, while for an access database is “?”, because access only supports positional parameters. Here is an example that use the class to find all customers living in London from the NorthWind database.

Int32 CustomerCount = Nablasoft.Helpers.DataAccess.Execute<Int32>(
   
delegate(DbCommand command, DbProviderFactory factory) {
      command.CommandType = System.Data.
CommandType.Text;
      command.CommandText = 
“SELECT COUNT(*) FROM Customers WHERE City = @city”;
      Nablasoft.Helpers.
DataAccess.AddParameterToCommand(
         command, factory, System.Data.
DbType.String, “city”, “London”); 
      
return (Int32)command.ExecuteScalar();
   });

The connection in the app.config is the following. As you can see the query text use a parameter name prefixed

<connectionStrings>
   <add 
         name=MainDatabase 
         connectionString=Database=Northwind;Server=localhost\SQL2000;User Id=sa;Password=ottaedro_2006@ 
         providerName=System.Data.SqlClient/>
 </connectionStrings>

Now the helper is database independent. I want to thank Ayende for it’s great example, his code is really amazing.

Alk.