Wednesday, January 21, 2009

Microsoft Certification

Today I passed the microsoft exam 70536 Microsoft .NET Framework - Application Development Foundation. I found it very interesting to prepare myself for this exam because despite that I program every day at work there were a lot of things that I simply didn't know that they exist. Other things I never understood completely and this exam helped me to find out how and why it works in this way. The exam itself was not very easy because the questions are very detailed and sometimes you simply have to have used some classes in order to know if a parameter is passed through the constructor or set with a property. The most difficult are the questions wher you have a list of steps and you have to bring them in the correct order; but not all steps may be needed. I find these kind of questions especially difficult because sometimes there is not only one way to accomplish the specified target. Anyway I am happy that I passed the exam and that now I can prepare myself for the next exam... a never ending story :-)

[Update]
Now I got access to the MCP website from where I also got the logo which I proudly put on the right menu bar :-)

Wednesday, January 7, 2009

Updating App.config

Today I faced the problem to update the App.config. There exist several solutions out there but I was not able to find a simple one. Therefore I decided to try out the new Linq to XML feature of .NET 3.5 and wrote the following method which updates the value of a specific key in the App.config file:

public static void UpdateAppConfig(string key, object value)
{
if (key == null)
throw new ArgumentNullException("key");

if (value == null)
throw new ArgumentNullException("value");

XDocument doc = XDocument.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var result = (from appSetting in doc.Descendants("appSettings").Descendants("add")
where appSetting.Attribute("key").Value.Equals(key)
select appSetting).FirstOrDefault();

if (result != null)
{
result.Attribute("value").SetValue(value);
doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
doc = null;
}
else
{
Console.WriteLine("The application setting with key '{0}' was not found!", key);
}
}

Blog statistics 2008

As I saw it is common to post some statistics about his blog. So also I will follow this "trend" :-)

First of all here the graph of accesse per day. Ultimately there is an average of 25 visits per day. The most visits were on July 1. There were 57 visits :-)



As you can see here most people get directed by a search engine to my page.



The most visitors access from London my page, but there are visitors all over the world.





I wish everybody a happy and good new year 2009 and I would be happy if you continue to visit my blog ;-)

Sunday, December 14, 2008

Localizing .NET applications

Most applications nowadays have to be localized in order to provide user interfaces in the language of the user who uses the application. The .NET framework offers a very handy mechanism to provide localization for your apps. It uses so called resource files (.resx) to store keys and the corresponding translated texts or images. If you want to know more on how to work with this translation mechanism take a look at this post.
The main problem with these files is to keep them in sync (for example when adding new strings) and to give translators an easy tool to make translation without requiring them to have visual studio installed on their computers.
I found a tool called "ResEx ... the composite, translation friendly .NET Resource editor" which can be found here that meets exactly this requriements. It provides a nice spreadsheet interface which makes it also for non programmers easy to translate the resources in the files. It is also possible to group resources together by using an underscore e.g. Menu_Home, Menu_Customers; they will all be shown under the tree node "Menu" which makes it easier to understand where the translations are used. Even adding and deleting localization languages is very easy.
The only thing which is missing is to have an automatic translation by using one of the several online translators available nowadays. I will suggest it on the forum and maybe this feature will be available in a future release.

Another very useful tool when working with resource files is the Resoucre Refactoring Tool on CodePlex. It helps you by localize strings in your source code by putting the string into the resource file and replacing the corresponding call in order to get a translated string.

Generating script for SQL Server database

Recently I had to deploy a project which used a Microsoft SQL Server database. During the deployment process all the tables and some predefined data should be created in the database of the machine on which the application is installed. I needed a simple .sql file which contains SQL instructions to create the schema and to insert the data. I thought that this would not be a big deal because SQL Server Management Studio has many tools and functionalities and for sure also one to do this since it is an essential part of software deployment. I used the export Wizard and everything worked well except that with the Wizard it is only possible to export the schema. I was very surprised that it is not possible to export the schema and the data.
After some research on the internet I found several commercial tools which are able to export also the data but I did not want to purchase such a tool only to export the data.
I found that there is an "API" for the SQL Server which is called SQL Server Management Objects (SMO) and SQL Server Replication Objects (RMO). These two "API's" can be used to get information from an SQL Server such as all the databases, all the tables in a database and all other information related to an SQL Server. I played a bit with them and there exists a method for each server object (such as databases, tables,...) which is called Script(). This method returns a StringCollection which can be used to re-create the SQL object. It is worth to give a look if you have to create, update or delete SQL objects from within code.
I tried to build a tool which is able to export a whole database, all its objects (function, triggers,...) and the data to a single sql file. I faced several problems. First it is important in which order the tables and constraints are created because otherwise the script would not run successfully. Second I had to generate insert statements for the data which has to consider all datatypes supported by SQL Server.
In some way I would have been able to solve these two issues but then I found the Microsoft SQL Server Database Publishing Wizard 1.1. This tool by Microsoft does exactly what I need. It exports one or more databases with their schema, objects and the data. If you have a similar issue I suggest you to use this one since it is free and worked fine for me :-)

Here you can find the official home page of the publishing wizard tool on CodePlex.

Monday, December 1, 2008

Show Collection of strings in GridView

Today I faced the following problem; I had a collection of strings which I wanted to show in a GridView. I tried to use the collection as datasource, but nothing was displayed. A quick and simple solution to this problem is the following:
- First you add a template column to the grid view
- In the template for the item you create a Literal control
- Then the Text property of the Literal is set to DataItem of the Container which is evaluated when databinding occurs

This can be accomplished with the following code:
<asp:gridview id="GridView1" runat="server" autogeneratecolumns="False" onrowdeleting="GridView1_RowDeleting">
<columns>
<asp:templatefield headertext="column">
<itemtemplate>
<asp:literal runat="server" id="customerNames" text="<%# Container.DataItem %>"></asp:literal>
</itemtemplate>
</asp:templatefield>
<asp:commandfield showdeletebutton="True">
</asp:commandfield>
</columns>
</asp:gridview>

This code sets a string collection as datasource and binds it to the gridview:
List<string> list = new List<string>();
list.Add("Customer1");
list.Add("Customer2");
list.Add("Customer3");
list.Add("Customer4");
list.Add("Customer5");
list.Add("Customer6");

this.GridView1.DataSource = list;
this.GridView1.DataBind();

But now is the question: how con you retrieve the value for example in the RowDeleting event. As accustomed to windows forms I tried:
this.GridView1.Rows[e.RowIndex].Cells[0].Text;

but that did not work. To get the correct text I had to use:
((Literal)this.GridView1.Rows[e.RowIndex].Cells[0].Controls[1]).Text;

Alltogether the cell contains 3 controls. The other two are LiteralControls with the Text '\r\n ' and the second one is the Literal control which holds the text.

Tuesday, November 25, 2008

INSERT if new and UPDATE otherwise

Recently I faced the following problem. I had to insert a big number of records into a PostgreSQL database. I have created a string which contains the various insert statements like below. The primary key is defined on the columns a,b.

INSERT INTO tablename (a,b,c) VALUES (1,2,'abc');
INSERT INTO tablename (a,b,c) VALUES (2,2,'def');
INSERT INTO tablename (a,b,c) VALUES (2,2,'ghi'); --generates an error!!
INSERT INTO tablename (a,b,c) VALUES (3,2,'ghi');

This worked fine until I encountered a duplicate primary key violation. The main problem with this was that after the error, the transaction was aborted and rolled back. So no record was inserted. I wanted instead that if such an error occurs, the existing record gets simply updated with the new values and if no record exists, it should be inserted. I searched the internet and there where different proposals but none of them really convinced me. I then came up with the following function:

CREATE OR REPLACE FUNCTION insert_update_record(a_in int, b_in int, c_in character varying)
RETURNS void AS
$BODY$
BEGIN
-- try to insert the record
BEGIN
INSERT INTO tablename (a,b,c) VALUES (a_in, b_in, c_in);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- if there is a duplicate key exception
-- update the record
UPDATE tablename SET c = c_in WHERE a = a_in AND b = b_in;
END;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

This function simply tries to insert the new record into the table and if there is a duplicate key exception it will update the record. The previous insert statements would then be converted to:

SELECT insert_update_record(1,2,'abc');
SELECT insert_update_record(2,2,'def');
SELECT insert_update_record(2,2,'ghi'); --generates an error but does not abort the transaction
SELECT insert_update_record(3,2,'ghi');

I did not make any performance tests, but I believe that this function is not much slower than the INSERT statements if there are not many duplicates; because it simply makes an insert and returns and only if there is an exception it does some additional work. Since this function is precompiled it may be that it is even faster than the INSERT statement. Anyway the function can help you solve the insert/update problem.
Of course you have to adjust the function according to your needs, but if you have some experience with programming it shouldn't be too difficult ;-)

UPDATE:
Based on the suggestion of Peter I made up a new function which is pratically an implementation for PostgreSQL of his pseudo SQL statements:
UPDATE sample
SET testno = 1;
WHERE test = 'PL/SQL';
IF SQL%ROWCOUNT ==0
THEN
/* Insert Statement */

END IF;

I have created then a table 'test' with the columns 'id' (pk), 'val1' and 'val2'. Then I converted the pseudo SQL into:

CREATE OR REPLACE FUNCTION update_insert(id_in integer, val1_in integer, val2_in integer)
RETURNS void AS
$BODY$
DECLARE
count int;
BEGIN
update test set val1 = val1_in, val2 = val2_in where id = id_in;
GET DIAGNOSTICS count = ROW_COUNT;

IF count = 0 THEN
INSERT INTO test (id, val1, val2) VALUES (id_in, val1_in, val2_in);
END IF;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

and provided also the function for this table with the exception handling:

CREATE OR REPLACE FUNCTION insert_update(id_in integer, val1_in integer, val2_in integer)
RETURNS void AS
$BODY$
BEGIN
-- try to insert the record
BEGIN
INSERT INTO test (id,val1,val2) VALUES (id_in, val1_in, val2_in);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- if there is a duplicate key exception
-- update the record
UPDATE test SET val1 = val1_in, val2 = val2_in WHERE id = id_in;
END;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;

Then I created with a small application the SQL statements that call these functions and I created them with differenct percentage of duplicates:

SELECT insert_update(1,101,-99);
and
SELECT update_insert(1,101,-99);

Here are the results of my performance measures:
1 000 statements
tried to insert every id twice -> 500 records in DB
update_insert: 250ms
insert_update: 250ms

100 000 statements
tried to insert every id twice -> 50 000 records in DB
update_insert: 37281ms
insert_update: 45125ms

100 000
every 10th record was already present -> 90 000 records in DB
update_insert: 63875ms
insert_update: 61500ms

10 000
all ids were the same -> 1 record in DB
update_insert 10016ms
insert_update 18703ms

I did the tests on my laptop; I know that they may not be precise because of running services in the background, but at least they give an intuition.
The result of my test:
- High number of duplicates -> the update/insert function is much faster
- Low number of duplicates -> the two functions are almost equally fast

I was surprised that there is not more difference between these two functions. I expected that the function with the exception would be much slower than the other one. I would suggest to use the update/insert function as proposed by Peter because exceptions should only be used in exceptional situations and avoided when possible.
Thanks Peter for the proposal...