Thursday 24 May 2012

Side effect of DbContextConfiguration.ProxyCreationEnabled Property

This does not seem to be documented anywhere on MSDN, that is why I would like to write a a quick post about it.

The example:

CustomerContext context = new CustomerContext();
context.Configuration.ProxyCreationEnabled = false;
var customers = context.Customers.ToList();


If DbContextConfiguration.ProxyCreationEnabled property is set to false, dbcontext will not load customers child objects unless Include method is called on customers object. Setting DbContextConfiguration.LazyLoadingEnabled property to true or false will have no impact on its behaviours.

If DbContextConfiguration.ProxyCreationEnabled is set to true, customers' child objects will be loaded automatically, and DbContextConfiguration.LazyLoadingEnabled value will control when child objects are loaded.


Tuesday 1 May 2012

Entity Framework POCO class in WCF

I encountered the following error when I tried to use generated POCO classes with WCF service:

Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy


My POCO classes already have DataContract&DataMember attributes applied.

The problem is that by default, entity framework dynamically generates proxy class whenever a instance of entity type is created. The entity type returned from or passed into the WCF service is actually a proxy object.

The fix is really simple, just turn off proxy object generation by setting
Configuration.ProxyCreationEnabled = false

Friday 10 February 2012

Use Explicit Waits in Selenium WebDriver Correctly

I encountered a very strange problem with selenium webdriver recently. I was using selenium to find a piece of text in a <p> element on a relative complexed webpage. The problem was sometimes selenium is able to find the text, and sometimes not. After some research, I found the following piece of information in selenium documentation:

Dependent on several factors, including the OS/Browser combination, WebDriver may or may not wait for the page to load. 

The documentation also suggests that WebDriverWait should be used for more consistent behaviour. And here is how to do it "officially":


            IWebDriver driver = new FirefoxDriver();
            driver.Url = "http://somedomain/url_that_delays_loading";
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
            {
                return d.FindElement(By.Id("someDynamicElement"));
            });


But when I tried it, it still sometimes throws NoSuchElementException even before specified timeout period. So I kept on reading, and according to the documentation:

This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. A successful return is for ExpectedCondition type is Boolean return true or not null return value for all other ExpectedCondition types.

That explains it. The anonymous method above neither return false nor null when it can't find the element. Therefore TimeoutException will not happen if it can't find the specified element. So the "official" example does not actually work.

Fortunately, only a simple change is required to make it work again;

            IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
            {
                try
                {
                    return d.FindElement(By.Id("someDynamicElement"));
                }
                catch
                {
                    return null;
                }
            });

Sunday 5 February 2012

Mock Linq Extension method in NHibernate ISession

There have been some discussion about the downside of repository layer in software design as Ayende Rahien posted in one of his blog. He suggested that with debut of modem ORM technologies, there is no need to have repository. His main argument is that repository layer adds complexities to the design and prevent developer access all the features of ORMs.

I agree with him. From my past experience with NHibernate and Entity Framework, adding a repository also creates a rather leaky repository layer, and sometimes performance takes a hit too.

However, there are still many reasons why people are still using Repository, two frequently mentioned are:

1. It is easier to use a differnt ORM technology later on.
2. We can easily mock repository for unit test.

Well, for #1, I don't think it is much of a issue. NHibernate and Entity Framework (as of version 4.2) are both quite mature. For me once I choose which one to use for a project, I never switch to use another one, simply because there is no need, the cost of switching to another ORM outweights the benefit.

I think #2 is more valid. I find entity framework is impossible to mock. It does not provide enough interfaces to substitute with my own implementation.  NHibernate is a lot better, so I decide to give it a try to see if I can mock ISession.

Personally I mostly use ISession linq extension methods querying data, so if I could mock these extension method, I would very happy to drop repository pattern. The problem with extension methods is that they are not actually a part of interface signature. Mocking framework will not be able to mock them (It will throw a exception at runtime).

Luckily I found a very good blog post by Daniel Cazzulino. Basicaly,  his idea is to have factory method to provide implementation for a extension method, and expose the the factory method as a public func property (delegate) so that we can substitute with our own version of func for testing purpose. Now, the only problem is that LinqExtensionMethods class in NHibernate does not provide public func property that you can access, I even dig into the source code and I found that there is no way I can mock ISession linq extension method directly.

So what about mocking it indirectly? After some head scratching, I realised that I can always write my own extension methods that wraps the original extension methods and expose a factory method to create the implementation. Here is how (based on NHibernate 3.2):


    public static class Extensions
    {
        internal static Func<ISessionIQueryable<object>> CreateIQueryable;
        
        public static IQueryable<T> LinqQuery<T>(this ISession session)
        {
            if (CreateIQueryable == null)
                return session.Query<T>();
            else
                return CreateIQueryable(session).Cast<T>();
        }
    }


So LinqQuery is now my accessing point for querying data, it wraps original Query<T> method inside.  If your want to mock LinqQuery for testing, you can simply do:


            List<Company> companies = new List<Company>
            {
                new Company() {ID = 1, Name = "Company A"},
                new Company() {ID = 2, Name = "Company" B}
            };
            Extensions.CreateIQueryable = session => companies.AsQueryable();


Happy mocking!



Sunday 8 January 2012

Entity Framework Performance Optimization For Include Method

Entity Framework is easier to use than NHibernate, my favourite API in EF is the Include method. For example, if you want to load object graph, you can simply use Include method like this:

var orders = context.Orders.Include("DeliveryAddress").Include("Customer");

In rare occasion, you want to load the entire object graph (not a good practice, but sometimes convenient), you might experience performance issue. If you ever looked at the SQL output of entity query, you will notice that the length of SQL output grows almost exponentially with the number of include methods you use and the depth of object graph you want to load. So you might end up with a query that takes minutes to run.

I recently found out that if you break up the include methods, the entity framework will still load the same data, but much faster:

var orders =  context.Orders.Include("DeliveryAddress");

orders =  context.Orders.Include("Customer");

In this case, the entity framework will generate two much shorter SQL queries, and combine the SQL results into one order object. For large database, this loading technique could save considerable amount of time.

Tuesday 27 December 2011

Use lambda expression as parameter for Include method in Entity Framework

One thing I find it very surprising with Entity Framework is that there is no overloaded Include method in DbQuery class that takes lambda expression as its parameter. Imagining that you want to load Customer's addresses with Customers, you have to do something like this:

context.Customer.Include("CustomerAddress")

There are a few drawbacks with this. First of all, it is not very refactor friend. Secondly there is no support from Intellisense. 

It would be great if you can write like this:

context.Customer.Include(m => m.CustomerAddress)

Well, as it turns out it is not very hard to accomplish that. We can create a extension method also called Include for DbQuery class with some help from Expression class as bellow:

public static class QueryHelper
    {
        private static string GetPath<T>(Expression<Func<T, object>> memberExpression)
        {
            var bodyString = memberExpression.Body.ToString();
            string path = bodyString.Remove(0, memberExpression.Parameters[0].Name.Length + 1);
            return path;
        }
 
        public static DbQuery<T> Include<T>(this DbQuery<T> query, Expression<Func<T, object>> memberExpression)
        {
            string includePath = GetPath<T>(memberExpression);
            return query.Include(includePath);
        }
    }