This blog is moved to
http://amalhashim.wordpress.com

Wednesday, April 14, 2010

Let's become an MVP

Here is your chance to prove the world how worthy you are. Lets showcase the efforts you have put to help communities.

Sunday, April 11, 2010

LINQ Performance Benchmark

Yesterday I was reading “LINQ To Objects Using C# 4.0” by Troy Magennis and find a good LINQ usage example. I got curious about how the LINQ implementation will perform and thought of writing this article.

The example is related to an entity having 3 fields State, LastName and FirstName. The aim is to Group the objects by state and sort by LastName. For calculating the execution time I am using Stopwatch class in System.Diagnosis namespace.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.IO;

namespace ConsoleApplication2
{
public class Customer
{
public string State { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}

class Program
{
static void Main(string[] args)
{
List<Customer> custList = FillListAndGetList();

Stopwatch sw = new Stopwatch();
sw.Start();
#region C# 2.0 Approach

///Sorting by LastName
custList.Sort(
delegate(Customer c1, Customer c2)
{
if (c1 != null && c2 != null)
return string.Compare(c1.LastName, c2.FirstName);
return 0;
});

///Sort and Groupby State [SortedDictionary]
SortedDictionary<string, List<Customer>>
sortedCust = new SortedDictionary<string, List<Customer>>();

foreach (Customer c in custList)
{
if (!sortedCust.ContainsKey(c.State))
sortedCust.Add(c.State, new List<Customer>());

sortedCust[c.State].Add(c);
}

foreach (KeyValuePair<string, List<Customer>>
pair in sortedCust)
{
Console.WriteLine("State : " + pair.Key);

foreach (Customer c in pair.Value)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });

custList = FillListAndGetList();
sw.Reset();
sw.Start();

#region LINQ Approach

var query = from c in custList
orderby c.State, c.LastName
group c by c.State;

foreach (var group in query)
{
Console.WriteLine("State : " + group.Key);

foreach (Customer c in group)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });
}

private static List<Customer> FillListAndGetList()
{
List<Customer> custList = new List<Customer>();
for (int i = 0; i < 1000000; i++)
{
Customer c = new Customer();
if (i % 2 == 0)
{
c.State = "State2";
c. FirstName = "FirstName2" + i.ToString();
c.LastName = "LastName2" + i.ToString();
}
else if (i % 3 == 0)
{
c.State = "State3";
c.FirstName = "FirstName3" + i.ToString();
c.LastName = "LastName3" + i.ToString();
}
else if(i % 7 == 0)
{
c.State = "State7";
c.FirstName = "FirstName7" + i.ToString();
c.LastName = "LastName7" + i.ToString();
}
else if (i % 11 == 0)
{
c.State = "State11";
c.FirstName = "FirstName11" + i.ToString();
c.LastName = "LastName11" + i.ToString();
}
else
{
c.State = "OtherState";
c.FirstName = "FirstName" + i.ToString();
c.LastName = "LastName" + i.ToString();
}

custList.Add(c);
}

return custList;
}
}
}

Once I ran the application, I got the following result.
C# 2.0 version : 627373008
LINQ version : 692116906
LINQ version has a slight performance problem, but compared to the chunk of code that has gone in 2.0 I think LINQ is far better.

Tuesday, April 6, 2010

C# – Read, Insert, Update, Delete From SQL Database

Code snippets for reading, inserting, updating and deleting from SQL database.

static void Read()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();

if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("Id = ", reader["Id"]);
Console.WriteLine("Name = ", reader["Name"]);
Console.WriteLine("Address = ", reader["Address"]);
}
}

reader.Close();
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("INSERT INTO EmployeeDetails VALUES(" +
"@Id, @Name, @Address)", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Amal Hashim");
cmd.Parameters.AddWithValue("@Address", "Bangalore");

int rows = cmd.ExecuteNonQuery();

//rows number of record got inserted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Update()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("UPDATE EmployeeDetails SET Name=@NewName, Address=@NewAddress" +
" WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Munna Hussain");
cmd.Parameters.AddWithValue("@Address", "Kerala");

int rows = cmd.ExecuteNonQuery();

//rows number of record got updated
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Delete()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("DELETE FROM EmployeeDetails " +
"WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);

int rows = cmd.ExecuteNonQuery();

//rows number of record got deleted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

Sunday, April 4, 2010

C# | 3 Tier Architecture

In this article I am going to explain how easily we can build up a 3 layered application using .net framework and c#. I have an Employee database. For demonstration I have cut the scope by talking only to one table, EmployeeDetails.

In 3 tier, we are dealing with

1. Data Access Layer

2. Business Layer

3. Presentation Layer

Here is the code of my Data Access Layer
static class DAL
{
const string ConnectionString = "server=.;initial catalog=Employee;user id=sa;password=sa123";

public static int ExecuteNonQuery(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

int rowsAffected = cmd.ExecuteNonQuery();

return rowsAffected;
}
}
}
catch
{
throw;
}
}

public static SqlDataReader GetReader(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

SqlDataReader reader = cmd.ExecuteReader();

return reader;
}
}
}
catch
{
throw;
}
}
}

To resemble the table EmployeeDetails I have created the following entity class
class EmployeeEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("Employee Name = ").Append(this.Name);
sb.Append(" Have Id = ").Append(this.Id);
sb.Append(" Lives In = ").Append(this.Address);

return sb.ToString();
}
}

Now comes the business layer


static class Employee
{
public static int AddEmployee(EmployeeEntity e)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("@Id", e.Id);
param[1] = new SqlParameter("@Name", e.Name);
param[2] = new SqlParameter("@Address", e.Address);

return DAL.ExecuteNonQuery("INSERT INTO EmployeeDetails VALUES(@Id, @Name, @Address)", param);
}

public static EmployeeEntity GetEmployee(int id)
{
SqlParameter[] param = new SqlParameter[1];
param[0] = new SqlParameter("@Id", id);

SqlDataReader reader = DAL.GetReader("SELECT * FROM EmployeeDetails WHERE Id = @Id", param);

if (reader.HasRows)
{
EmployeeEntity emp = new EmployeeEntity();
while (reader.Read())
{
int temp = 0;
int.TryParse(reader["Id"].ToString(), out temp);
emp.Id = temp;
emp.Name = reader["Name"].ToString();
emp.Address = reader["Address"].ToString();

break;
}
return emp;

}
else
return null
;
}
}

Finally my presentation
class Program
{
static void Main(string[] args)
{
Employee.AddEmployee(new EmployeeEntity() { Id = 1, Name = "Amal", Address = "MyAddress" });
Employee.AddEmployee(new EmployeeEntity() { Id = 2, Name = "Hashim", Address = "Hashim Address" });
Employee.AddEmployee(new EmployeeEntity() { Id = 3, Name = "Rooney", Address = "Manchester" });

EmployeeEntity emp = Employee.GetEmployee(1);

Console.WriteLine(emp);
}
}

For better demonstration, you can think the presentation layer as a windows form application. With a 3 textboxes and one button. You can enter Id, Name and Address and use the button event for adding the data.

Sql | Parameterized Queries

In msdn forums, a common question is regarding database retrieval and updation. To help such users I thought of bringing up this article. I want to give a concrete example, which will demonstrate the usage. To start with, I have a Employee database with a table named EmployeeDetails witht the following structure.

image

In the below code sample, I will show how to insert a record and get it back. To avoid the problems that can cause from SQL Injection, .Net framework has introduced Parameterized queries. Another way to get around this situation is using stored procedures.

using System;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
string connectionString = "server=.;initial catalog=employee;user id=sa;password=sa123";

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO" + "EmployeeDetails Values(@Id, @Name, @Address)", conn))
{
cmd.Parameters.Add("@Id", System.Data.SqlDbType.Int);
cmd.Parameters.Add("@Name", System.Data.SqlDbType.VarChar);
cmd.Parameters.Add("@Address", System.Data.SqlDbType.VarChar);

cmd.Parameters["@Id"].Value = 4;
cmd.Parameters["@Name"].Value = "Rooney";
cmd.Parameters["@Address"].Value = "Manchester United";

int rowsInserted = cmd.ExecuteNonQuery();

Console.WriteLine("Rows inserted = " + rowsInserted);
}

using (SqlCommand cmd = new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine(reader["Id"].ToString() + " " + reader["Name"].ToString() + " " + reader["Address"].ToString());
}
}
else
{
Console.WriteLine("No Rows");
}
}
}
}
}
}

Hope this was helpful.

.Net Framework | Value Types

Value type holds data in the variable. They are stored in “Stack”. Because of this the performance is good and causes minimal overhead. Mainly there are three value types

1. In built

2. User defined(structs)

3. Enums

All the above are derived from System.Value

Type Bytes Occupied Range
System.SByte 1 -128 to 127
System.Byte 1 0 to 255
System.Int16 2 -32768 to 32767
System.Int32 4 -2147483648 to 2147483647
System.UInt32 4 0 to 4294967295
System.Int64 8 -9223372036854775808 to 9223372036854775807
System.Single 4 –3.402823E+38 to 3.402823E+38
System.Double 8 -1.79769319486232E+308 to 1.79769319486232E+308
System.Decimal 16 -79228162514264337593543950335 to 79228162514264337593543950335
System.Char 2  
System.Boolean 4  
System.DateTime 8 1/1/0001 12:00:00 AM to 12/31/9999 11:59:59 PM
System.Boolean 4 True/False
System.IntPtr Platform Dependent  

Nullable Types

In some scenarios we might need to store the value null in the basic types. For doing that we can make the type nullable as shown below

bool? isValid = null;
//or
Nullable<bool> isSelected = null;


Structures or User Defined Types


Struct as mentioned is also a value type and is stored on the stack. Struct resembles class, but have several differences. Structures are composite types. They form a meaningful  data. The most common example give for structures is the Point type available in System.Drawing namespace. Each point can be represented using x and y coordinate and hence a structure can be formed as


struct Point
{
public UInt32 X;
public UInt32 Y;
}



I have enhanced the Point structure as shown below



using System;
using System.Text;

namespace ConsoleApplication2
{
struct Point
{
public UInt32 X;
public UInt32 Y;

public Point(uint x, uint y)
{
this.X = x;
this.Y = y;
}

public static Point operator +(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public static Point operator -(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("The current point has X = ").Append(this.X.ToString())
.Append(" and Y = ").Append(this.Y.ToString());
return sb.ToString();
}
}

class Program
{
static void Main(string[] args)
{
Point p1 = new Point(10, 20);
Point p2 = new Point(20, 30);

p1 += p2;

Console.WriteLine(p1);

}

}
}

As you can see the structure has a parameterized constructor and can have methods. It also has overloaded operators.


Note: We can’t use default constructors in Structure. Default constructor is used by the framework to initialize the fields in structure.


Note: Always make use of a structure only if the entire data in it constitute less than 16 bytes.


Enumerations or Enum


Enums are grouped constants. They are introduced mainly to make the code readable.


Lets extend the above application by adding an Enum Direction. Based on the direction the point will be moved.


using System;
using System.Text;

namespace ConsoleApplication2
{
struct Point
{
public UInt32 X;
public UInt32 Y;

public Point(uint x, uint y)
{
this.X = x;
this.Y = y;
}

public static Point operator +(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public static Point operator -(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("The current point has X = ").Append(this.X.ToString())
.Append(" and Y = ").Append(this.Y.ToString());
return sb.ToString();
}

public void Move(Direction d)
{
switch (d)
{
case Direction.Up:
if (this.X > 0)
this.X--;
break;
case Direction.Down:
if (this.X < 1000)
this.X++;
break;
case Direction.Left:
if (this.Y > 0)
this.Y--;
break;
case Direction.Right:
if (this.Y < 1000)
this.Y++;
break;
default:
break;
}
}
}

enum Direction
{
Up,
Down,
Left,
Right
}

class Program
{
static void Main(string[] args)
{
Point p1 = new Point(0, 0);
Console.WriteLine(p1);
p1.Move(Direction.Left);
Console.WriteLine(p1);
p1.Move(Direction.Down);
Console.WriteLine(p1);
p1.Move(Direction.Left);
Console.WriteLine(p1);
p1.Move(Direction.Right);
Console.WriteLine(p1);
}

}
}

Friday, April 2, 2010

MVP – Visual C# – 2010



Dear Amal Hashim,


Congratulations! We are pleased to present you with the 2010 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Visual C# technical communities during the past year.


The Microsoft MVP Award provides us the unique opportunity to celebrate and honor your significant contributions and say "Thank you for your technical leadership."


Toby Richards
General Manager
Community & Online Support