Wednesday, April 14, 2010
Let's become an MVP
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 Layerstatic 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.
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