Jul 31 2007

AJAX 1.0 in VS 2008

Category:Bil@l @ 06:52

Two good posts by the Web Development Tools team that you should read if you are already working on AJAX 1.0 and want to start using VS 2008:

1- Upgrading ASP.NET AJAX 1.0 Websites and Web Applications to .NET Framework 3.5
2- Using VS 2008 to target ASP.NET AJAX 1.0

Hope this helps,
Regards

Tags:

Jul 29 2007

www.Hookedonlinq.com

Category: DLinq | LinqBil@l @ 20:10

I would like to invite you to check this wonderful website dedicated to LINQ (XML, Objects, database, Dataset, etc ...)

www.hookedonlinq.com

Make sure you visit it!
Regards

Tags: ,

Jul 29 2007

Implicitly Typed Local Variables

Category: C# 3.0Bil@l @ 14:56

Implicitly Typed Local Variables is a general prupose way of declaring variables without the need to specify the data type. The data type will be infered implicitly from the initializer data. It is strongly typed variable
that cannot take as input a data type other than the one used on initialization time. This proves that "var" is not the same as "Dim" in VB/.NET. Dim can take different data types, however, "var" only takes values of the same data type that was used upon initialization.


 Things you cannot do with Implicitly Typed Local Variables
  You cannot declare an ITLV without specifying an initializer.
  You cannot set the value of a VAR to NULL.
  You cannot change the data type of an already defined VAR variable.
  
 Things you cannot do with Implicitly Typed Local Variables
  You can assign one VAR to another.
 
 An example of using a "var" is as follows:

 // Simple string
 var intValue= 5;

 // Array of integers
 var arrInt= new[] {1, 2, 3, 4};

 // Array of objects
 var arrObject= new[] {new Point(), new Point()};


 "var" is mainly used to shape the results of a Query Expression because sometimes you might return a result that cannot be used explicitly as follows:

 var results=  from c in db.customers
   select new MyCustomer {
    ID= c.ID,
    Name= c.Name
   };

 Now, we can navigate through the results as follows
 foreach (MyCustomer cust in results) {
  Console.WriteLine("{0}, {1}", cust.ID, cust.Name);
 }
 
 
Hope this helps you,
Regards

Tags:

Jul 29 2007

Extension Methods

Category: C# 3.0Bil@l @ 14:50

Extension methods are a way to extend the functionality of existing types by defining methods that can be invoked either by using the normal instance method syntax or in a static way. They are
defined in a static class, and each extension method should be a static one. The first parameter for the extension method should be preceeded by "this", which denotes the type being extended.
If there are any requried parameters, they can be placed infront of the first one.  

An example will show you how to extend the string class to add a method to check if a string week day is a valid weekday. For instance, Monday is a valid week day, while Mondy is not a valid week day!

First of all we define the static class that should contain the extension methods:

 public static class MyExtendedMethods
    {
        public static bool IsValidWeekDay(this string s) {
            Regex regEx= new Regex(@"^(Sun|Mon|(T(ues|hurs))|Fri)(day|\.)?$|Wed(\.|nesday)?$|Sat(\.|urday)?$|T((ue?)|(hu?r?))\.?$");
            return regEx.IsMatch(s);
        }
    }

As you can see the extension method should be placed inside a static class. Even the extension method should be designated with static keyword.

The static method, IsValidWeekDay, has no parameters and through the use of "this string s" this means this method will operate on the string class. The method returns a boolean value whether the string it is operating on returns true which means it is a valid weekday or false which means the string operating on is not a valid weekday.

Here is a sampel code on how to use the above extension method.

            string currDay= "Monday";
            if (currDay.IsValidWeekDay())
                Console.Write("{0} is a valid day!", currDay);
            else
                Console.Write("{0} is not a valid day!", currDay);

The above shows how to access the extension method as an instance method, if you want, you can also access this method through the use of static method:

            string currDay= "Monday";
            if (MyExtendedMethods.IsValidWeekDay(currDay))
                Console.Write("{0} is a valid day!", currDay);
            else
                Console.Write("{0} is not a valid day!", currDay);

Hope this helps you!
Rergards

Tags:

Jul 29 2007

Anonymous Types

Category: C# 3.0Bil@l @ 13:42

Anonymous types is a new feature of C# 3.0. It allows developers to creat local objects without the need to have a real signature of a class. This is helpful sometimes, when you have methods that take as input a large number of input parameters. What you can do is simply create a new anonymous type and use it through out the local body of the method. This way, you will be dealing with a strongly type class containing all input parameters instead of dealing with seperate fields.

 1.
 Anonymous types allows grouping data into a class that is created
 automatically at compile-time.

 2.
 var x= new {a=1, b=2, c="Bilal"};
 
 The above statement is compiled and the following is created:
 class __Anonymous1
 {
  private int _a= 3;
  private int _b= 5;
  private int _c= "some text";

  public int a { get{ return _a; } set{ _a = value;} };
  public int b { get{ return _b; } set{ _b = value;} };
  public int c { get{ return _c; } set{ _c = value;} };
 }

 3.
 When we define a subset of a class as an anonymous type,
 we declare the anonymous type without the need to specify
 properties names, this is called Projection Initializer.

Hope this helps,
Regards

Tags:

Jul 29 2007

Lambda Expressions

Category: C# 3.0Bil@l @ 13:37

 1.
 Lambda Expressions have been introduced as an improvement
 to the anonymous methods in C# 2.0 as a way to make them
 more compact.

 2.
 Lambda expression consists of:
  . Parameter List
  . =>
  . Expression

 3.
 Parameters of Lambda Expression can be implicitly
 or explicitly typed. Ex:
  . (int i) => (i+1)
  . (i) => (i+1)

 4. You can have single or multiple parameters Ex:
  . (x,y) => return x*y

 5. If you want to pass a lambda expression with no parameters:
  . () => return "Empty Parameters";


Think of Lambda expressions as an anonymous method in a more compact style. Take this example:

Suppose we have a list of employees named "customers". You want to query this list using a System defined Extension method called "WHERE" as follows:

var query= customers.Where( c => c.Country == "Lebanon"; );

As you can see the above lambda expression is composed of:

1- c: Which is the input parameter
2- => token
3- c.Country == "Lebanon": this is the expression that will be applied to every record retrieved from the customers list. So, while the query is looping through the records of customers,
it will apply the lambda expression, if the result of the expression is true, then it will include the current record in the result of the query.

We could have done the same using Anonymous methods as in C# 2.0:

var query= customers.Where(
  delegate (Customer c) {
   return c => c.Country == "Lebanon";
  }
 );


Notice also that the lambda expression can be a series of statements and not only a single simple statement.

(x) => { Console.WriteLine("Hello World"); return 0; }

All of the above expressions could have been placed with the { and } too!

Hope this helps,
Regards

Tags:

Jul 28 2007

Optimistic Concurrency in DLinq

Category: DLinq | LinqBil@l @ 17:26

Dlinq handles optimistic concurrency implicitly when exexuting SubmitChanges() method. However, you can handle the resolution of the conflict and deciding on how to solve a conflict that happened.

Usually, when two users retrieve the same record, one of them updates the record and submit changes, then anotehr user comes in and performs another update, here the conflict is detected.
Here is an example:

    Product product = db.Products.First(p => p.ProductID == 1);
   

    // Open a second connection to the database to simulate another user
    // who is going to make changes to the Products table               
    Northwind otherUser_db = new Northwind(connString) { Log = db.Log };
    Product otherUser_product = otherUser_db.Products.First(p => p.ProductID == 1);
    otherUser_product.UnitPrice = 999.99M;
    otherUser_product.UnitsOnOrder = 10;
    otherUser_db.SubmitChanges();


    // first user re-updates the UnitPrice
    product.UnitPrice = 777.77M;

    bool conflictOccurred = false;
    try {
        db.SubmitChanges(ConflictMode.ContinueOnConflict);
    } catch (OptimisticConcurrencyException ex) {
        Console.WriteLine("* * * OPTIMISTIC CONCURRENCY EXCEPTION * * *");
        foreach (OptimisticConcurrencyConflict aConflict in ex.Conflicts) {
            Product prod = (Product)aConflict.Object;
            Console.WriteLine("The conflicting product has ProductID {0}", prod.ProductID);
            Console.WriteLine();
            Console.WriteLine("Conflicting members:");
            Console.WriteLine();
            foreach (OptimisticConcurrencyMemberConflict memConflict in aConflict.GetMemberConflicts()) {
                string name = memConflict.MemberInfo.Name;
                string yourUpdate = memConflict.CurrentValue.ToString();
                string original = memConflict.OriginalValue.ToString();
                string theirUpdate = memConflict.DatabaseValue.ToString();
                if (memConflict.HaveModified) {
                    Console.WriteLine("'{0}' was updated from {1} to {2} while you updated it to {3}",
                                      name, original, theirUpdate, yourUpdate);
                } else {
                    Console.WriteLine("'{0}' was updated from {1} to {2}, you did not change it.",
                        name, original, theirUpdate);
                }
            }
            Console.WriteLine();
        }
        conflictOccurred = true;
    }


The above example shows how the conflict is detected and displays a detailed information on all the conflicting members.

Inside the catch statement, we can resolve the conflict as follows:


RefreshMode.OverwriteCurrentValues
-------------------------------------
catch (OptimisticConcurrencyException ex) {
        ex.Resolve(RefreshMode.OverwriteCurrentValues);
        db.SubmitChanges();
    }

With OverwriteCurrentValues, the second user who tried to update the record, his/her update will be disgarded and the record in the database will be maintained!


RefreshMode.KeepCurrentValues
-------------------------------------
catch (OptimisticConcurrencyException ex) {
        ex.Resolve(RefreshMode.KeepCurrentValues);
        db.SubmitChanges();
    }

With KeepCurrentValues, the second user will override any changes in the database record done by the first user. Any column that the second update didn't change, it will preserve its original data from the database and not from the update done by the first user if any.


RefreshMode.KeepChanges
-------------------------------------
catch (OptimisticConcurrencyException ex) {
        ex.Resolve(RefreshMode.KeepChanges);
        db.SubmitChanges();
    }

With KeepChanges, the second user will override any changes in the database record done by the first user. Any column that the second update didn't change, it will be assigned the value that was updated by the first user.


Hope this post really helps you. I want to post this to make sure I have a small post as reference to keep myself on the safe side not to forget it!!

Regards

Tags: ,

Jul 28 2007

Direct SQL Execution in DLinq

Category: DLinq | LinqBil@l @ 17:23

A very nice feature I find is to be able to execute a custom SQL statement in case you find the functionalities provided by the DataContext object is limited.

There are two main methods:

ExecuteQuery, which has two flavors of the ExecuteQuery method

1- Without parameters
 IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
  @"select c1.custid as CustomerID, c2.custName as ContactName
   from customer1 as c1, customer2 as c2
   where c1.custid = c2.custid"
 );

We are executing a T-SQL statement by passing the query to the ExecuteQuery method. The return type if a collection of Customer classes.

2- With Parameters
 IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
  "select contactname from customers where city = {0}",
  "London"
 );

As you can see above, we are passing the City parameter to get a parameterized query.

There is important note here which is that, ExecuteQuery is capable of materializing the results into a collection of objects as long as the returned columns match the corresponding
entity class' columns.

Also, you can execute a command against the database using the ExecuteCommand as follows:

    db.ExecuteCommand("UPDATE Products SET UnitPrice = UnitPrice + 1.00");

In the above command, we are updating the UnitPrice of the Products table.


Hope this helps,
Regards

 

Tags: ,

Jul 28 2007

Transactions in DLinq

Category: DLinq | LinqBil@l @ 17:18

There are two ways in DLinq to work with Transactions. One is preferred to another.

1. Using the TransactionScope class - Preferred One

using(TransactionScope ts = new TransactionScope()) {
 db.SubmitChanges();
 ts.Complete();
}

2. Using the BeginTransaction on the SqlConnection

Product prod = q.Single(p => p.ProductId == 15);
if (prod.UnitsInStock > 0)
 prod.UnitsInStock--;

db.Transaction = db.Connection.BeginTransaction();
try {
 db.SubmitChanges();
 db.Transaction.Commit();
}
catch {
 db.Transaction.Rollback();
 throw;
}
finally {
 db.Transaction = null;
}


Hope this helps,
Regards

Tags: ,

Jul 28 2007

Read-Only DataContext in DLinq

Category: DLinqBil@l @ 17:14

As you know every object retrieved using Linq to SQL is being tracked by the DataContext class for any changes that happen in the life time of the object in the application. However, this takes more processing and off course performance will be affected.
Suppose one time you want to load some records from the database and bind them to a data control without the need to do any changes, instead we only want to load the records and show them on a a web page or windows form.

Here we need to tell the DataContext class not to track changes on the following query that is to be excecuted:

// Disable tracking
db.ObjectTracking = false;

// Prepare a query expression
var q = db.Customers.Where( c => c.City = "London");

// Execute the query
foreach(Customer c in q)
 Display(c);

As you can see this can save some performance in case you are loading lots of records!

Hope this helps,
Regards

Tags: