Tuesday, March 31, 2009

Code Hightlight and Indention

Google Blogger is one of popular Blogs. Maybe millions of people own the blogger's blog. I like its convenient, it integrated with many nice features such as YouTube, Picasso Web Albums, Google Adsense etc. Unfortunately, it is not enough good for Sofware developer, the reason is that it doesn't provide the Code Hightlight feature. Worst of all, it will automatically trim the spaces in front of each line when you post your blog. It will spoil the indented code and effect the readability of code snippet. It is bad news, isn't it?

Of course, you can search for the corresponding Add-in to solve the problem. But I don't find the good add-in for blogger so far. Some of them are not convenient, some are no nice format, and some decrease the performance of website because they will read some information from server.

Now, I find the best way to solve it finnally. It's very easy. The key is one website I will strongly recommend for you. That is 代码发芽网(Which means code germination. Funny, aha.). You can paste your code snippet to it, and select the language such as C#, Javascript, Python, php etc. Then submit it. Finnally the code snippet will convert the format according to the language syntax and present with highlight style. Now you only need to select the result code and copy to your blog post. That's it.

It is not yet over. Blogger will automatically trim the spaces described before. So there is a peice of advice for you. If you place your code snippet inside the <> < /pre > in Compose Mode, everything is ok. You will get the indented code with highlight. Here are some sample demos.

C# Code Snippet:
public class Bar
{
[CallTracingAttribute("In Bar ctor")]
public Bar() {}
[CallTracingAttribute("In Bar.Calculate method")]
public int Calculate(int x, int y){ return x + y; }
}

Javascript Code Snippet:
function bookmark(title, url) {
if (document.all)
window.external.AddFavorite(url, title);
else if (window.sidebar)
window.sidebar.addPanel(title, url, "")
}
Python Code Snippet:
#!/usr/bin/env python

'makeTextFile.py -- create text file'

import os
ls = os.linesep

# get filename
while True:
fname = raw_input('Enter file name: ')
if os.path.exists(fname):
print"*** ERROR: '%s' already exists" % fname
else:
break

# get file content (text) lines
all = []
print "\nEnter lines ('.' by itself to quit).\n"

# loop until user terminates input
while True:
entry = raw_input('> ')
if entry == '.':
break
else:
all.append(entry)

# write lines to file with proper line-ending
fobj = open(fname, 'w')
fobj.writelines(['%s%s' % (x, ls) for x in all])
fobj.close()
print 'DONE!'
Only regret is that it can't deal with the html-like language in this way, because the blogger will parse them. Apart from this, it can't support the generic syntax.

QCon Beijing Will Be Open


QCon is Enterprise Software Development Conference for the leader of group, architect, project manager and senior software developer. The area it focuses on cover through Architecture Design, SOA, Agile, Case Study, etc. QCon is hosted by InfoQ. Since March, 2007, it has been hold four times in London UK, San Francisco USA. Upcoming conference will be hold in Beijing, China during April 7 to 9.

In QCon Beijing, Some of speakers include:
Rod Johnson: Spring Creator;
Martin Fowler: Author of the great books "Analysis Patterns" and "Refactoring", The Chief Scientist of Thoughtworks;
Randy Shoup: eBay senior architect;
Jeff Bar: Amazon Cloud Computin architect;
Dylan Shiemann: Dojo Toolkit founder;
Floyd Marinescu: Author of "EJB Patterns", InfoQ and TheServerSide founder;
Mao XinSheng: IBM China Web 2.0 chief architect;
Li Wei: Siments China Research Center chief architect;

Sunday, March 29, 2009

Using Extension Methods to Verify the Method Calling

Using the extension method provided by C# 3.0 as the new feature, you can add the new methods for the compiled assembly to meet the need of extensible. In addition to this, extension method can also be effective to reduce duplicate code and improve the reusability of system if you are able to combine the generic and type inference. For example, the method like this:

public class CustomerDAL

{

    public IEnumerable<Customer> FindCustomers(string roleName)

    {

        return from customer

            in context.Customer

               where customer.RoleName.Equals(roleName)

               select customer;

    }

}

It will throw the NullReferenceException if you invoke it by this way as below when it returns null:

Customer customer = new CustomerDAL().FindCustomers(Role.Admin).First();

So we have to verify the result. If it is null, the custom exception should be thrown:

public IEnumerable<Customer> FindCustomers(string roleName)

{

    IEnumerable<Customer> customers = from customer

            in context.Customer

            where customer.RoleName.Equals(roleName)

            select customer;

    if (customers == null)

    {

        throw new MyException(“Cann’t find the customers.”);

    }

    return customers;

}

 

The logic of verification implemetation will spread through the everywhere in the system if there are too many methods which need to be verified. It is difficult to reuse these code, and it is bad smell absolutely.

Craig Andera post the blog to solve this problem. He wrote:
A NullReferenceException would be thrown, but we wanted something more specific. So we came up with this:

public static T OrThrow<T>(this T obj, Exception e) {

    if (obj == null) {

        throw e;

    }

    return obj;

}

 

Using the OrThrow() method, the invoking way might be changed like this:

Customer customer = new CustomerDAL().

    FindCustomers(Role.Admin).OrThrow

    (new MyException(“Can’t find Customer”)).First();

 

Craig continues to say:
the OrThrow extension method is generic on the type it’s invoked on, and it returns that type, so you can insert it into a chained expression and you don’t lose any intellisense. And because of type inference, you don’t actually have to specify the type, which cleans up the expression a bit.

That is, OrThrow() method can be applied to any type. Following this idea, we can create an instance as default value to avoid to throw the NullReferenceException using the extension method:

public static T Instance<T>(this T obj) where T:new()

{

    if (obj == null)

    {

        obj = new T();

    }

    return obj;

}

 

Due to type parameter T need to create an instance, we must add the constraint with new(). So that we can’t use the Instance<T> extension method for abstract type or interface type such as IEnumerable. But it is effective to method like this:

public class ListObject

{

    public List<string> Foo()

    {

        return null;

    }

}

 

Through by using Instance() method, we can invoke the related properties and methods of List instance safely. For example, we can use the Count property as below:

Console.WriteLine(new ListObject().Foo().Instance().Count);

Thursday, March 19, 2009

A Common Base Class for LINQ To SQL

Introduction

Language-Integrated Query (LINQ) is a set of features in Visual Studio 2008 that extends powerful query capabilities to the language syntax of C# and Visual Basic. As a part of LINQ, LINQ to SQL provides a run-time architecture for managing relational data as objects. To some extent, it equals to an ORM tool or framework such as NHibernate and Castle based on the .NET framework. It becomes our preferred choice gradually when we want to access databases.

In LINQ to SQL, all variables in the Data Model of a relational database can be strongly typed, which provides the benefit of compile-time validation and IntelliSense. We can fetch the data from the database using a query expression (it includes query syntax and method syntax).

However, the strongly typed feature is not conducive to abstract the common logic of data operations, so the developer has to define a specific class to handle the entity object. It results in a large number of repeated codes If we can implement the base class which encapsulates common operations such as Select, Where, Add, Update, and Delete, it will be useful for N-tier applications.

Using the Code

Using my base class for LINQ to SQL, you can simply implement the class to access a database without a line of code. What you should do is to let your class derive my base class, like this:

public class EmployeeAccessor : AccessorBase<Employee, NorthwindDataContext>

{

}

 

Now, you can add, update, delete, or select the data object with it. Please refer to the Unit Test Method:

    [TestMethod()]

    public void UpdateEmployee()

    {

        EmployeeAccessor accessor = new EmployeeAccessor();

        IList<Employee> entities = accessor.Where(e => e.EmployeeID == 1);

 

        if (entities != null && entities.Count > 0)

        {

            entities[0].FirstName = “Bruce”;

            entities[0].LastName = “Zhang”;

 

            accessor.Update(entities[0], true, true);

        }

    }

 

You may even let the Employee entity derive my base class directly:

public partial class Employee : AccessorBase<Employee, NorthwindDataContext>

{

}

 

Its behavior is very similar to the Rich Domain Model like Martin Fowler said in his article titled Anemic Domain Model.

 

The implementation of the base class

 

The implementation of the query function is very simple. We can invoke a method called GetTable<TEntity>() in the DataContext of LINQ, then invoke some LINQ operations of the GetTable<TEntity>() method, and pass the Lambda Expression to it:

public IList<TEntity> Where(Func<TEntity, bool> predicate)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate).ToList<TEntity>();

}

 

We can also expose the method which accepts the condition clause using a dynamic query:

public IList<TEntity> Where(string predicate, params object[] values)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate, values).ToList<TEntity>();

}

 

The implementation of the Update method (also the Delete method) is more complex. Though we can use the Attach methods LINQ introduces, there are some constraints for them. So, I have provided a couple of Update methods for different situations.

At first, we must consider whether the entity has relationship with other entities or not. If yes, we have to remove the relationship from it. I have defined a Detach method using Reflection technology, like this:

    private void Detach(TEntity entity)

    {

        foreach (FieldInfo fi in entity.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))

        {

            if (fi.FieldType.ToString().Contains(“EntityRef”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    fi.SetValue(entity, null);

                }

            }

            if (fi.FieldType.ToString().Contains(“EntitySet”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    MethodInfo mi = value.GetType().GetMethod(“Clear”);

                    if (mi != null)

                    {

                        mi.Invoke(value, null);

                    }

 

                    fi.SetValue(entity, value);

                }

            }

        }

    }

For EntityRef<T> fields, we may set their values to null by calling the SetValue of FieldInfo to remove the relationship. However, we can’t do EntitySet in the same way because it is a collection. If set to null, it will throw an exception. So, I get the method information of the field and invoke the Clear method to clear all the items in this collection.

For the update operation, we can pass the changed entity and update it. The code snippet is shown below:

    public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

    {

        InitDataContext();

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship between the entitis

                Detach(originalEntity);

            }

            m_context.GetTable<TEntity>().Attach(originalEntity);

            update(originalEntity);

 

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

Notice that the entity which will be updated must have a timestamp, or it will throw an exception.

Don’t worry about the correctness of the final result when we remove the relationship between the entities. The Attach method is just responsible for associating the entity to a new instance of a DataContext to track the changes. When you submit the changes, the DataContext will check the real value in the mapping database and update or delete the record according to the passed entity. Especially, you should take an action such as Cascade in the database if you want to cascade the delete between the foreign key table and the primary key table.

If the entity has no relationship with others, you may pass “false” to the hasrelationship parameter, like this:

accessor.Update(entities[0],true,false);

 

It’s terrible to create the timestamp column for your data table which exists, maybe it will affect your whole system. (I strong recommend you to create the timestamp column for your database, it will improve the performance because it won’t check all columns if they have changed during handling the concurrency.) My solution to this issue is to pass the original entity and update it with the Action<TEntity> delegate, like this:

/// <summary>

/// Update the entity which was passed

/// The changedEntity cann’t have the relationship between the entities

/// </summary>

/// <param name=”originalEntity”>It must be unchanged entity in another data context</param>       

/// <param name=”update”>It is Action<T>delegate, it can accept Lambda Expression.</param>

/// <param name=”hasRelationship”>Has relationship between the entities</param>

public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

{

    InitDataContext();

    try

    {

        if (hasRelationship)

        {

            //Remove the relationship between the entitis

            Detach(originalEntity);

        }

 

        m_context.GetTable<TEntity>().Attach(originalEntity);

 

        update(originalEntity);

 

        SubmitChanges(m_context);

    }

    catch (InvalidCastException ex)

    {

        throw ex;

    }

    catch (NotSupportedException ex)

    {

        throw ex;

    }

    catch (Exception ex)

    {

        throw ex;

    }

}

Concurrency Issue

Considering the concurrency issue, I give the default implementation for it by defining a virtual method called SubmitChanges. It will handle concurrency conflicts by the rule of last submit win. This method is as shown below:

/// <summary>

/// It provides the default policy to handle the corrency conflict

/// </summary>

/// <param name=”context”>Data Context</param>

protected virtual void SubmitChanges(TContext context)

{

    try

    {

        context.SubmitChanges(ConflictMode.ContinueOnConflict);

    }

    catch (ChangeConflictException)

    {

        context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

        context.SubmitChanges();

    }

    catch (Exception ex)

    {

        throw ex;

    }

}

 

You may override the method in your subclass if you want to change the policy to handle the concurrency conflicts.

 

Others

Maybe you have noticed that the InitDataContext method is invoked in all methods to access the data. Its implementation is like this:

private TContext m_context = null;

 

private TContext CreateContext()

{

    return Activator.CreateInstance<TContext>() as TContext;

}

 

private void InitDataContext()

{

    m_context = CreateContext();

}

 

Why do we need to create a new instance of DataContext for each method? The reason is the caching policy in the DataContext. If you create a new instance of the DataContext and query the data from the database with it, then change its value and execute the same query with the same instance, the DataContext will return the data stored in the internal cache rather than remap the row to the table. For more information, please refer to LINQ in Action.

So, the best practice is to create a new instance of the DataContext for each operation. Don’t worry about the performance, the DataContext is a lightweight resource.

This article on CodeProject.

 

More details, please visit this article on my blog.

Saturday, March 7, 2009

Strategy Pattern and Delegate

Strategy Pattern will encapsulate a family of algorithm and make them interchangeable. So we can define the unified interface for the algorithm. It represents the polymorphism of OOD. For instance, we will develop a tool to calculate the tax. Assumed that the tax is divided into the personal income tax and enterprise tax. We can apply the Strategy Pattern into it and abstract the calculation of tax into the interface ITaxStrategy:

public interface ITaxStrategy

{

    double Calculate(double income);

}

 

The concrete tax strategies will implement the ITaxStrategy interface:

public class PeronalTaxStrategy : ITaxStrategy

{

    public double Calculate(double income)

    {

        //Implementation

    }

}

public class EnterpriseTaxStrategy : ITaxStrategy

{

    public double Calculate(double income)

    {

        //Implementation

    }

}

 

At the same time, we will define the utility class to provide the clients with convenient.

public class TaxOp

{

    private ITaxStrategy strategy;

    public TaxOp(ITaxStrategy strategy)

    {

        this.strategy = strategy;

    }

    public double GetTax(double income)

    {

        return strategy.Calculate(income);

    }

}

Now, the clients can invoke the related operation of TaxOp class to get the tax according to concrete strategy object which is passed as parameter of constructor.

public class App

{

    public static void Main(string[] args)

    {

        TaxOp op = new TaxOp(new PersonalTaxStrategy());

        Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

    }

}

 

It follows the idea of OOD. However, we can make use of the delegate syntax in C# for some simple algorithms. It will simplify our implementation. Maybe it will violate the idea of OOD, but it provides the extensibility also.

 

For the same example given before, we can modify the interface to delagate type:

public delegate double CalculateTax(double income);

 

Of course, we should provide the different implemenation:

public class Tax

{

    public static double CalculatePersonalTax(double income)

    {

        //Implementation

    }

    public static double CalculateEnterpriseTax(double income)

    {

        //Implementation

    }

}

 

Accordingly, we must modify the TaxOp Class:

public class TaxOp

{

    private CalculateTax calDel;

    public TaxOp(Calculate calDel)

    {

        this.calDel = calDel;

    }

    public double GetTax(double income)

    {

        return calDel(income);

    }

}

 

And the implementation of Clients program:

public class App

{

    public static void Main(string[] args)

    {

        TaxOp op = new TaxOp(new CalculateTax(Tax.CalculatePersonalTax));

        Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

    }

}

 

Two solutions are more or less the same. The code snippet is also similar. But the idea based on the essence of design is different completely. It’s the difference between OO and OP. The former encapsulates the behavior in an object; the latter handles the method directly, and uses the delegate to provide the extensibility. In fact, the delegate represents the feature of Functional Programming nearly. It seams like a pointer to the function in C++. In other words, the delegate is another ways of abstraction. It is more flexible than interface type. After C# 2.0 introduced the anonymous method, and C# 3.0 introduced the Lambda expression, delegate becomes more and more useful and popular on C# programming. Before C# 2.0, I prefer to interface; now I prefer to delegate. Even we may use the delegate type to provide the brand new implementation of some design patterns such as Strategy Pattern, Command Pattern etc.

Friday, September 12, 2008

How to know Transaction Is Successful

Based on .Net Framework, it is convient to use transaction with System.Transactions.TransactionScope class. If no error occurs in the transaction scope, the TransactionScope object will complet, otherwise rollback.

In some situations, we need execute some business logics after transaction complet successfully. Note that we don’t add some business logic code lines after complet() method. In another word, we must place these business logics out of the transaction scope. However, the transaction object had been disposed out of using statement. So, how to know the transaction is successful?

Transaction object exposes the event called TransactionCompleted and provides TransactionStatus which is enumeration type. TransactionStatus enumeration type includes four values: Aborted, Committed, Active and InDoubt. Then we can make a decision depending on the value of TransactionStatus which is belong to TransactionInformation object. TransactionInformation object is a property of Transaction instance.

The sample code is as below:

using (TransactionScope ts = new TransactionScope())

{

    Transaction transaction = Transaction.Current;

    transaction.TransactionCompleted += pro.OnCompleted;

    pro.UpdateEmployee();

    pro.DeleteCustomer();

    ts.Complete();          

}

 

void OnCompleted(object sender, TransactionEventArgs e)

{

    Debug.Assert(sender.GetType() == typeof(Transaction));

    Debug.Assert(object.ReferenceEquals(sender,e.Transaction));

    Transaction transaction = e.Transaction;

    switch (transaction.TransactionInformation.Status)

    {

        case TransactionStatus.Aborted:

            m_TransactionCommitted = false;

            //Not to do something when failed

            break;

        case TransactionStatus.Committed:

            m_TransactionCommitted = true;

            //do something when success

            break;

        default:

            m_TransactionCommitted = false;

            break;

    }

}

Friday, August 15, 2008

A Little Bit Regret for Generic in C#

In our project, I defined the ThrowHelper helper class to help us throw the customized exception. For instance, I defined a exception as below:

public class EmployeeException : ApplicationException

{

    public EmployeeException()

        : base()

    { }

 

    public EmployeeException(string message)

        : base(message)

    { }

 

    public EmployeeException(string message, Exception innerException)

        : base(message, innerException)

    { }

}

 

Then we might define the method to throw it to be invoked by other developer conveniently:

public static class ThrowHelper

{

    public static EmployeeException ThrowEmployeeException(string message)

    {

        LogService.Error(message);

        throw new EmployeeException(message);

    }

 

    public static EmployeeException ThrowEmployeeException(string message, Exception innerException)

    {

        LogService.Error(message, innerException);

        throw new EmployeeException(message, innerException);

    }

}

 

The problem is that we need to add the method such as before if we defined a number of customized exceptions. It’s tedious. The developer must dislike this way whenever.

Can we use the generic type to solve this problem? For example, we may define a new version method using generic type as below:

public static class ThrowHelperGeneric<TCustomException>

    where TCustomException : ApplicationException, new()

{

    public static TCustomException ThrowCustomException(string message)

    {

        LogService.Error(message);

        throw new TCustomException(message);

    }

 

    public static TCustomException ThrowCustomException(string message, Exception innerException)

    {

        LogService.Error(message, innerException);

        throw new TCustomException(message, innerException);

    }

}

 

Opps, it’s regretful. It can’t support to invoke constructor with parameter based on .Net framework. We have to use the reflection technology to solve it:

public static class ThrowHelperGeneric<TCustomException>

    where TCustomException : ApplicationException, new()

{

    public static TCustomException ThrowCustomException(string message)

    {

        LogService.Error(message);

        TCustomException exception = (TCustomException)typeof(TCustomException).GetConstructor(new Type[] { typeof(string) }).

            Invoke(new object[] { message });

 

        throw exception;

    }

 

    public static TCustomException ThrowCustomException(string message, Exception innerException)

    {

        LogService.Error(message, innerException);

        TCustomException exception = (TCustomException)typeof(TCustomException).GetConstructor(new Type[] { typeof(string), typeof(Exception) }).

            Invoke(new object[] { message, innerException });

 

        throw exception;

    }

}

 

It’s a terrible choice. I don’t like to do in this way. Even though we can use new() in the where constraint, how come Microsoft can’t provide the similiar operator or keyword in the where constraint to constrain the type of the parameter in the constructor? Like this:

public static class ThrowHelperGeneric<TCustomException>

    where TCustomException : ApplicationException, new(), new(string), new(string, Exception)

{

    public static TCustomException ThrowCustomException(string message)

    {

        LogService.Error(message);

        throw new TCustomException(message);

    }

 

    public static TCustomException ThrowCustomException(string message, Exception innerException)

    {

        LogService.Error(message, innerException);

        throw new TCustomException(message, innerException);

    }

}

I don’t know whether it will support this function in the furture version with C#. Is it too difficult?

Friday, August 1, 2008

Programming Standard for Our Team

1. Exception Handling
1) Deprive all custom exceptions from System.ApplicationException, and putting all custom exceptions into WD.AIATools.Common.Exceptions namespace;
2) Define three overloaded version for constructor, such as:

public class ActionParamsException : ApplicationException

{

    public ActionParamsException()

        : base()

    {    }

 

    public ActionParamsException(string message)

        : base(message)

    {    }

 

    public ActionParamsException(string message, Exception ex)

        : base(message, ex)

    {    }

}

3) Provide a helper method which includes the logging operation for your custom exception in ThrowHelper class:

    public static ActionParamsException ThrowActionParamsException(string message, Exception ex)

    {

        LogService.Error(message, ex);

        return new ActionParamsException(message, ex);

    }

4) In Data Access Layer, try to catch the exception which is thrown by .NET Framework, and re-throw the custom exception by invoking the helper method with ThrowHelper. For example:

        try

        {

            Foo();

        }

        catch (SqlException ex)

        {

            throw; //Avoid

            ThrowHelper.ThrowCustomException(“message”, ex); //OK

        }

        catch (NotSupportedException ex)

        {

            ThrowHelper.ThrowCustomException(“message”, ex); //OK

        }

        catch (Exception ex)

        {

            ThrowHelper.ThrowCustomException(“message”, ex); //OK

        }

        finally //if necessary

        {

            //do something

        }

5) Don’t catch the exception in Business Logic Layer otherwise it is necessary.
6) In Presentation Layer, it includes two cases:
a) Show the error information on the current page through by catching the exception;
b) Link to the error page which includes the error information with Exception.Message;
7) Don’t catch the exception inside for or foreach statement.

 

2. Robust Check Policy
1) Avoid throwing the NullReferenceException. Check whether the object is null before using it:

if (someObject != null)

{

    //Do something;

}

else //if necessary

{

    //throw the custom exception or else

}

2) Never return the null value especially if the object is collection:

public IList GetSomeList()

{

    //Something to do;

    if (NoItemInCollection)

    {

        return new List(); //OK

        return null; //Avoid;

    }

}

3) Always explicitly initialize an array of reference types using a for loop:

public class MyClass{}

 

const int ArraySize = 10;

MyClass[] array = new MyClass[ArraySize];

for (int index = 0; index < ArraySize; ++index)

{

    Array[index] = new MyClass();

}

4) Prefer to use foreach statement instead of for statement;
5) Try to check what the instance’s type is before casting the reference type by using “is” operator:

if (someObject is Foo)

{

    Foo object = (Foo)someObject;

}

//Or

Foo object = someObject as Foo;

6) Remember to dispose the resource when using the unmanaged resource; Always use a using statement in this situation.

3. Code Practices
1) Avoid putting multiple classes in a single file;
2) Never hard-code a numeric value; always declare a constant instead;
3) Avoid providing explicit values for enums unless they are integer powers of 2:

//Correct

public enum Color

{

    Red, Green, Blue

}

Note: Putting all enum types into the specific file.
4) Use String.Empty instead of “”;
5) When building a long string, use StringBuilder, not String;
6) Always have a default case in a switch statement;

Wednesday, July 30, 2008

Common Base Class for LINQ to SQL

Language-Integrated Query (LINQ) is a set of features in Visual Studio 2008 that extends powerful query capabilities to the language syntax of C# and Visual Basic. As a part of LINQ, LINQ to SQL provides a run-time architecture for managing relational data as objects. To some extent, it equals to ORM tool or framework such as NHibernate and Castle based on .NET framework. It becomes our preferred choice gradually when we want to access the database.

In LINQ to SQL, all variables in the Data Model of a relational database can be strongly typed which provides the benefit of compile-time validation and IntelliSense. We can fetch the data from the database using query expression (it includes query syntax and method syntax.)

However, the strongly typed feature is not conducive to abstract the common logic of data operations so the developer has to define a specific class to handle the entity object. It results in a large number of repeated codes. If we can implement the base class which encapsulates the common operations such as Select, Where, Add, Update and Delete, it will be useful for N-Tier application.

Fortunately, the generic type will help us to achieve our goal. We can invoke a method called GetTable() in DataContext of LINQ. For example, we can implement the Where method which accepts the Lambda expression to find the result we want to get:

public IList<TEntity> Where(Func<TEntity, bool> predicate)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate).ToList<TEntity>();

}

 

It’s simple. Even, we can expose the method which accepts the condition clause using Dynamic Query:

public static class DynamicQueryable

{

    public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)

    {

        return (IQueryable<T>)Where((IQueryable)source, predicate, values);

    }

 

    public static IQueryable Where(this IQueryable source, string predicate, params object[] values)

    {

        if (source == null) throw new ArgumentNullException(“source”);

        if (predicate == null) throw new ArgumentNullException(“predicate”);

        LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);

        return source.Provider.CreateQuery(

            Expression.Call(

                typeof(Queryable), “Where”,

                new Type[] { source.ElementType },

                source.Expression, Expression.Quote(lambda)));

    }

}

public IList<TEntity> Where(string predicate, params object[] values)

{

    InitDataContext();

    return m_context.GetTable<TEntity>().Where(predicate, values).ToList<TEntity>();

}

 

Of course, the query function is not a problem because we don’t need the properties of the entity when we invoke these methods and don’t care about the composition of Lambda Expression.

The key issue is how to update or delete the record of data table. You know, we must fetch the entity which is going to be operated before updating or deleting it. The keyword to search is often its identity. Furthermore, Object Identity and Change Tracking in Data Context need the object’s identity to track the changing of it. Usually, we would add the Id column which is identity or Guid for each table. Then we can fetch the entity object according to it:

    public void Update(Employee employee)

    {

        LinqSampleDataContext context = new LinqSampleDataContext();

 

        Employee emp = this.Where(e => e.EmployeeID == employee.EmployeeID);

        emp.FirstName = “First Name”;

        emp.LastName = “Last Name”;

 

        context.SubmitChanges();

    }

 

Obviously, we don’t know the entity’s properties if we use the generic type such as TEntity like above. Without the keyword how do we associate the changes with the existing record? LINQ introduces the Attach method which can attach the changed object to the context. There are three overloaded versions as below:
Attach(Object entity): Attaches an entity to the DataContext in an unmodified state;
Attach(Object entity, bool asModified): Attaches all entities of a collection to the DataContext in either a modified or unmodified state.
Attach(Object entity, Object orginal): Attaches an entity to the DataContext in either a modified or unmodified state by specifying both the entity and its original state.

Attach method is used to associate the deserialized entities to a new instance of a DataContext. However, we can associate the entity in one DataContext to another DataContext by using it. In update or delete case, this method is very useful. For example, we want to update the record according to a changed entity from another DataContext:

    public void Update(TEntity changedEntity)

    {

        InitDataContext();

 

        try

        {

            m_context.GetTable<TEntity>().Attach(changedEntity, true);

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

 

It looks good, but not enough. We can’t attach a changed entity unless the entity has a TimeStamp column in the corresponding table. Therefore, we should add a column whose type is TimeStamp in SQL Server 2005, or set the IsVersion property to true for Id property in LINQ to SQL Designer. My advice is to create a TimeStamp column for your datatable, and it will improve the performance because it won’t check all columns whether they are changed during handling concurrency.

In fact, we can pass the original entity with generic type also. The only problem is how to pass the values you want to change. The solution to this problem is using Action delegate. The code snippet is as below:

    public void Update(TEntity originalEntity, Action<TEntity> update)

    {

        InitDataContext();

        try

        {

            m_context.GetTable<TEntity>().Attach(originalEntity);

            update(originalEntity);

 

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

 

Now we can invoke it passing Lambda expression like this:

    [TestMethod()]

    public void UpdateWithAction()

    {

        LinqSampleDataContext context = new LinqSampleDataContext();

        EmployeeAccessor accessor = new EmployeeAccessor();

 

        Employee employee = context.Employees.Single(e => e.EmployeeID == 1);

 

        accessor.Update(employee, t => { t.FirstName = “First”; t.LastName = “Last”; });

    }

 

Unfortunately, the test case can’t pass sometimes. It will throw a NotSupportedException. And the message of exception is:
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

Why? What happens? The real reason is the entity we handle has some associations with other entities. Please see figure 1:

linqbaseclass01

Figure 1 : The entity with association

If you remove all relationships in Employee table, and re-generated the data model, the test case would pass.

What shall we do? Of course, to remove all relationships of table explicitly is not a good way to solve the issue. It will impact on the whole data model and can’t be accepted when we develop the application. I found one guy, Steve Michelotti, raised one solution to solve it. That was to provide one method called Detach to remove the relationships using partial class:

public partial class Contact

{

    public void Detach()

    {

        foreach (Address address in this.Addresses)

        {

            address.Detach();

        }

    }

}

 

public partial class Address

{

    public void Detach()

    {

        this._AddressType = default(EntityRef<AddressType>);

        this._State = default(EntityRef<State>);

    }

}

 

Good job! But it is not perfect. First, it’s too complex because we must define the Detach method for every entity which has association with others. Second, we can’t abstract it to the base class in this way. In the base class, we don’t know the specific type of TEntity. In this case, we should turn to the reflection technology. It’s my way:

    private void Detach(TEntity entity)

    {

        foreach (FieldInfo fi in entity.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))

        {

            if (fi.FieldType.ToString().Contains(“EntityRef”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    fi.SetValue(entity, null);

                }

            }

            if (fi.FieldType.ToString().Contains(“EntitySet”))

            {

                var value = fi.GetValue(entity);

                if (value != null)

                {

                    MethodInfo mi = value.GetType().GetMethod(“Clear”);

                    if (mi != null)

                    {

                        mi.Invoke(value, null);

                    }

 

                    fi.SetValue(entity, value);

                }

            }

        }

    }

 

For EntityRef fields, we may set their values to null by calling the SetValue of FieldInfo class to remove the relationship. However, we can’t do EntitySet in the same way because it is a collection. If set to null, it will throw exception. So I get the method information of the field and invoke the Clear method to clear all items in this collection. Finally, my implementation of Update method is as below:

    public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

    {

        InitDataContext();

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship between the entitis

                Detach(originalEntity);

            }

            m_context.GetTable<TEntity>().Attach(originalEntity);

            update(originalEntity);

 

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

 

Delete operation is similar except we don’t need invoke the second version of Attach (Attach(object entity, bool asModified)). Here is the code snippet:

    public void Delete(TEntity entity, bool hasRelationship)

    {

        InitDataContext();

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship between the entities;

                Detach(entity);

            }

 

            m_context.GetTable<TEntity>().Attach(entity);

            m_context.GetTable<TEntity>().DeleteOnSubmit(entity);

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

    public void Delete(IList<TEntity> entities, bool hasRelationship)

    {

        InitDataContext();

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship

                foreach (TEntity entity in entities)

                {

                    Detach(entity);

                }

            }

 

            m_context.GetTable<TEntity>().AttachAll(entities);

            m_context.GetTable<TEntity>().DeleteAllOnSubmit(entities);

 

            m_context.SubmitChanges();

        }

        catch (ChangeConflictException)

        {

            m_context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            m_context.SubmitChanges();

        }

    }

 

Don’t worry about the correctness of final result when we remove the relationship between the entities. The Attach method is just responsible for associating the entity to a new instance of DataContext to track the change. When you submit the changes, DataContext will check the real value in the mapping database and update or delete the record according to the passed entity. Especially, you should take an action such as Cascade in the database if you want to cascade delete between foreign key table and primary key table, see figure 2.

linqbaseclass02

Figure 2: Set the delete rule

If no action, the System.Data.SqlClient.SqlException will be thrown and the message of it when you delete the entity as Primary Key table, like this:
The DELETE statement conflicted with the REFERENCE constraint “FK_Orders_Employees”. The conflict occurred in database “Northwind”, table “dbo.Orders”, column ‘EmployeeID’.

Maybe you notice the InitDataContext method is invoked in all methods to access the data. Its implementation like this:

    private TContext m_context = null;

 

    private TContext CreateContext()

    {

        return Activator.CreateInstance<TContext>() as TContext;

    }

 

    private void InitDataContext()

    {

        m_context = CreateContext();

    }

 

Why do we need create a new instance of DataContext for each method? The reason is Caching policy in DataContext. If you create a new instance of DataContext and query the data from the database though by it, then change its value and execute the next query though by the same instance, the DataContext will return the data stored in the internal cache rather than remapping the row to the table. For more information, please refer to the Linq in Action.

So, the best practice is to create a new instance of DataContext for each operation. Don’t worry about the performance, the DataContext is lightweight resource.

Let’s consider about the concurrency issue. The default option is Optimistic Concurrency. When the values are to be saved, the DataContext would check the previous values to see if they have been changed. If conflict occurs, the DataContext would need to know whether to automatically overwrite the previous changes, keep the previous changes, or somehow merge the changes.

The concurrency issue is not within the scope of this article. We can’t say which one of three ways is the best or worst, it depends on the business situation. Usually, I will handle concurrency by the rule of last submit win. So I encapsulate the SubmitChanges method and define it as visual method, if necessary, the subclass may override it:

public class AccessorBase<TEntity, TContext>

    where TEntity : class, new()

    where TContext : DataContext, new()

{

    private TContext m_context = null;

 

    /// <summary>

    /// It provides the default policy to handle the corrency conflict

    /// </summary>

    /// <param name=”context”>Data Context</param>

    protected virtual void SubmitChanges(TContext context)

    {

        try

        {

            context.SubmitChanges(ConflictMode.ContinueOnConflict);

        }

        catch (ChangeConflictException)

        {

            context.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

            context.SubmitChanges();

        }

        catch (Exception ex)

        {

            throw ex;

        }

    }

 

    /// <summary>

    /// Update the entity which was passed

    /// The changedEntity cann’t have the relationship between the entities

    /// </summary>

    /// <param name=”originalEntity”>It must be unchanged entity in another data context</param>       

    /// <param name=”update”>It is Action<T>delegate, it can accept Lambda Expression.</param>

    /// <param name=”hasRelationship”>Has relationship between the entities</param>

    public void Update(TEntity originalEntity, Action<TEntity> update, bool hasRelationship)

    {

        InitDataContext();

 

        try

        {

            if (hasRelationship)

            {

                //Remove the relationship between the entitis

                Detach(originalEntity);

            }

 

            m_context.GetTable<TEntity>().Attach(originalEntity);

 

            update(originalEntity);

 

            SubmitChanges(m_context);

        }

        catch (InvalidCastException ex)

        {

            throw ex;

        }

        catch (NotSupportedException ex)

        {

            throw ex;

        }

        catch (Exception ex)

        {

            throw ex;

        }

    }

}

 

Now, we have a common base class which can be derived to handle the entity. For example:

public class EmployeeAccessor : AccessorBase<Employee, NorthwindDataContext>

{

}

 

You don’t need implement any method. It’s more convenient to access the Employee table by using an instance of EmployeeAccessor:

    [TestMethod()]

    public void UpdateEmployee()

    {

        EmployeeAccessor accessor = new EmployeeAccessor();

        IList<Employee> entities = accessor.Where(e => e.EmployeeID == 1);

 

        if (entities != null && entities.Count > 0)

        {

            entities[0].FirstName = “Bruce”;

            entities[0].LastName = “Zhang”;

 

            accessor.Update(entities[0], true, true);

        }

    }

 

You may let Employee entity derive my base class directly even:

public partial class Employee : AccessorBase<Employee, NorthwindDataContext>

{

}

 

Its behavior is very similar with Rich Domain Model like Martin Fowler said in the article which title is Anemic Domain Model.

 

Download Source Code: LinqSample_Src.zip     368KB

 

Note: The database which my sample use is Northwind in SQL Server 2005 and I add a new column which type is TimeStamp for each table.