Monthly Archives: April 2008

ObjectQuery, LINQ to Entities and IQueryable

The return type of a LINQ query is an IQueryable, even a LINQ to Entities query.

Here is a screenshot of a LINQ to Entities query at design time (code is NOT being debugged).

But when the query has been processed, it’s no longer an IQueryable, but an ObjectQuery.

What’s going on here?

At design time, the compiler recognizes that it’s a LINQ query and therefore assumes the return will be an IQueryable.

However LINQ to Entities queries are sent to ObjectServices which return an ObjectQuery, so after it’s processed, it is actually an ObjectQuery.

So, since it’s an ObjectQuery after all, wouldn’t it be nice to leverage ObjectQuery features like MergeOptions on a LINQ to Entities query? You can!

But how? At design time, the query is an IQueryable, not an ObjectQuery and doesn’t have MergeOptions.

No worries. ObjectQuery implements IQueryable.

So you can cast the LINQ to Entities query to an ObjectQuery, set the MergeOption and, as Jeffrey Palermo would say, party on the LINQ to Entities query (though he may not be likely to say that in the context of Entity Framework ;-)).

Using context As New AdventureWorksLTEntitiesDim query = From c In context.Customer Where c.LastName.StartsWith(“S”)Dim objquery = CType(query, ObjectQuery(Of Customer))objquery.MergeOption = MergeOption.OverwriteChangesDim cust = query.ToList.FirstConsole.WriteLine(cust.LastName)cust.LastName = cust.LastName.Trim & “___XYZ”cust = query.ToList.FirstConsole.WriteLine(cust.LastName)End Using

Notice that I’m still performing the operations against the  LINQ query after I cast it to the ObjectQuery.

I could also have done something like

Dim custs = objquery.Execute(MergeOption.OverwriteChanges)

Thanks to Danny for reminding me about the casting! The blog post is intended to lock it into my brain.

Compiled Queries in Entity Framework

I was fiddling with compiled queries yesterday and thought I would share what I saw as results. This is anything but laboratory benchmark testing so take it for what it’s worth. I did only a very simple query to start with, finding SalesOrders whose total is greater than a given number.

You can do this with Entity SQL or LINQ to Entities. Here is my LINQ to Entities compiled query:

Dim compQuery = CompiledQuery.Compile(Of AdventureWorksLTEntities, Decimal,
 IQueryable(Of SalesOrderHeader))( _
 Function(ctx As AdventureWorksLTEntities, total As Decimal) _
 From order In ctx.SalesOrderHeader _Where (order.TotalDue >= total) _
 Select order)

To interpret this, Compile’s signature looks like this:

Compile(list of args, returntype)(delegate)

It takes a list of arguments and a return type then performs an operation (defined in the delegate) on the arguments. I’m defiining this compilation to recieve an AdventureWorksLTEntities instance and a decimal and the return will be an IQueryable of SalesOrderHeaders.

VB
CompiledQuery.Compile(Of AdventureWorksLTEntities, Decimal, _ IQueryable(Of SalesOrderHeader))
C#
CompiledQuery.Compile<AdventureWorksLTEntities, Decimal, IQueryable<SalesOrderHeader>>

For the delegate, I use a labmda epxression that says what to do with the parameters which is to build the query.

VB
(Function(ctx As AdventureWorksLTEntities, total As Decimal) _
From order In ctx.SalesOrderHeader _
Where (order.TotalDue >= total) _
Select order)

c#
(ctx, total) => 
from order in ctx.SalesOrderHeader
where (order.TotalDue >= total)
select order)

 

The whole query is tied to a variable

Dim myCompiledQuery=CompiledQuery.Compile(....

Then when I want to run the query, I invoke it and pass in the parameters

 

Dim AWEntities As New AdventureWorksLTEntities
Dim orderTotal=200
Dim orders As ObjectQuery(Of SalesOrderHeader) = compQuery.Invoke(AWEntities, orderTotal)

The first time the compiled query is run, it still has to compile, but after that it uses the results of the compilation and can swap in the parameters without needing to recreate the generated command tree.

You can see a big difference between running the query without pre-compilation and running it with the compiled query.

Brian Dawson does some more intense testing and compares LINQ to Entities to Entity SQL as well in this blog post. But I just needed to actually do it myself, rather than only reading about it.

LINQ to SQL also has compiled queries. Rico Mariani has a series of posts on this starting here.

 

MVC with Visual Basic video series

Bill Burrows has created a series of videos on MVC and is now working on a new series based on Scott Guthrie’s MVC tutorial posts (which are all in C#) but using VB instead. I was surprised to find a pointer to my recent MVC post as a “rare example” of MVC with VB (and it’s only one little post so I found that to be sad) so I’m happy Bill is doing these. It gives a leg up to VB developers who find it hard to try to learn something that is VERY new and convert the C# syntax in their brain at the same time.

Here’s the list of topics covered

  An Overview of the MVC Pattern
  Setting up the MVC Preview Environment
  URL Routing
  Setting up New Pages
  MVC Controller Actions 
  Creating HTML in Views 
  MVC – Putting it all together

Thanks to Beth for the heads up.

nHibernate 2.0 Alpha

Entity Framework owes a lot to the feedback of the nHibernate crew who, as Roger Jennings so aptly states, “were responsible for making the Entity Framework folks finally understand what persistence ignorance is all about”.

The PI side of EF still has a long way to go, so in the meantime nHibernate continues to get stronger and stronger.

The alpha of a new version that logs over 100,000 lines of code changes was just released.

I know those guys are beyond frustrated with the current state of Entity Framework and the persistence of people like me who are curious about it and continue to share what I learn with whoever wants to listen, rather than just telling them to run away from data centric programming and join the ALT.NET wave. But what can I say. I embrace the options even if I can’t become expert in them all.

Anyway, this release is a huge accomplishment and to have it be done with the dedication of what it takes in an Open Source environmnet to roll out a tool that can be used in big enterprise applications is really impressive.

LINQ to SQL (and LINQ to Entities) performance improvements for VIsual Basic

Highlights of this post from Timothy Ng of the VB team:

“Over the last few months, the VB and Data Programmability teams were working on fixing a performance problem with LINQ to SQL (which also manifested in LINQ to Entities). The issue was that LINQ to SQL was generating sub optimal T-SQL queries when the VB LINQ queries included filters over nullable columns.”

“The good news is that the LINQ to SQL team has a fix to their code generation to recognize this pattern, and now they emit the SQL code that you would have expected to emit”

“In other words, LINQ to SQL (and LINQ to Entities – we made the same fix there) is now smart enough to pass three-value logic from VB to SQL.”

Congrats to Matthieu Mezil who became a father yesterday and an MVP today!

I’m not sure which he is more excited about! Just kidding. But considering that his wife is going to let him go to the MVP summit only 2 weeks after their first child is born, it makes one wonder!

Hey Matthieu – what’s this about making fun of being a VB MVP? 😉

Matthieu has spent a lot of time in the MSDN forums answering questions on Entity Framework. Thanks to him, I’ve had time to write my book while he gives the team a run for their money on answering questions. 🙂