What Do ObjectQuery’s Builder Methods Build

Until Beta 2 ObjectQuery’s builder methods used to build a Command Tree. There were multiple problems with that:

· Duplicate code - there is already a component that builds Command Trees from Entity SQL.

· Caching – Command Trees are expensive to hash and thus – difficult to cache.

· Tracing – getting a meaningful canonical description of an ObjectQuery required a converting the Command Tree back to text which was a step back.

 

Therefore, in Beta 2 ObjectQuery was refactored to build Entity SQL internally instead of a Command Tree. When the ObjectQuery is about to be executed, the internal Entity SQL representation is sent to the Entity SQL Parser to build a Command Tree for it. Thus ObjectQuery now leverages the same Query Plan Cache as EntityCommand – queries are compiled only the first time they are executed; subsequent executions reuse the already compiled query plan (as long as the cache is not full).

 

Reusing the Entity SQL Parser, however, means that ObjectQuery may now surface exceptions from it. That’s not bad as long as there is an API to get to the internal Entity SQL command text. In Beta 2 such an API was missing, but that’s fixed in Beta 3. Similarly to EntityCommand, a CommandText property is exposed now off ObjectQuery.

 

The same example that showed how to get the native SQL, also shows how to get the Entity SQL for a given ObjectQuery:

 

            // Create an ObjectContext

            using (Northwind.Northwind northwind = new Northwind.Northwind(NorthwindConnectionString))

            {

                // Create an ObjectQuery

                ObjectQuery<Northwind.Product> products = northwind.Products

                                                          .Where("LEFT(it.ProductName, 1) = 'C'")

                                                          .OrderBy("it.ProductName");

                // Make sure the connection is open

                northwind.Connection.Open();

                // Display the Entity SQL built for the ObjectQuery

                Console.WriteLine("\n\n---------------------------------------------------------");

                Console.WriteLine("Entity SQL");

                Console.WriteLine("---------------------------------------------------------");

                Console.WriteLine(products.CommandText);

                // Display the T-SQL generated for the (Entity SQL of the) ObjectQuery

                Console.WriteLine("\n\n---------------------------------------------------------");

                Console.WriteLine("T-SQL");

                Console.WriteLine("---------------------------------------------------------");

                Console.WriteLine(products.ToTraceString());

                // Render the result to make sure the query is valid

                Console.WriteLine("\n\n---------------------------------------------------------");

                Console.WriteLine("Result");

                Console.WriteLine("---------------------------------------------------------");

                foreach (Northwind.Product product in products)

                {

                    Console.WriteLine("{0,2}: {1}", product.ProductID, product.ProductName);

                }

            }