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);
}
}