Convenient CLR Methods aren't always the best for LINQ to Entities

Not all CLR methods can be used when building LINQ to Entities or LINQ to SQL queries. The method needs to be something that can be expressed in the native query language. So if you have a date field, you can't use ToShortDateString in the query since there is no equivalent. You'll get runtime exceptions when you use these as the query compiler goes to work.

There are others that work, but you may not want them.

Case in point is doing a query to search on the first letter of a property.

String.StartsWith

VB

From con In context.Contacts _
                     Where con.LastName.StartsWith("S")

C#

from con in PEF.Contacts
                    where con.LastName.StartsWith("S")
                    select con

Both render this WHERE clause in TSQL:

WHERE (CAST(CHARINDEX(N'S', [Extent1].[LastName]) AS int)) = 1

I've been told this will make DBAs run away screaming.

 

String.SubString

VB

From con In PEF.Contacts _
                     Where con.LastName.Substring(0, 1) = "S"

C#

from con in PEF.Contacts
                          where con.LastName.Substring(0, 1) == "S"
                          select con

These render this WHERE clause:

WHERE N'S' = (SUBSTRING([Extent1].[LastName], 0 + 1, 1))

 

Visual Basic's Left does the cleanest job

From con In PEF.Contacts _
                    Where Left(con.LastName, 1) = "S"

Gives us:

WHERE N'S' = (LEFT([Extent1].[LastName], 1))

Other options such as attempting to use an indexer (lastname(0) or lastname

 

Be careful out there.

#1 Kristofer Andersson on 9.22.2008 at 1:41 AM

Hi Julie,Just a FYI (but a noteworthy one): Linq-to-SQL does a _much_ better job than EF at translating Linq expressions such as the ones in your example into efficient SQL queries. For example, a .StartsWith("something") in the where clause of a linq query against a L2S data context is translated into a like clause that will be able to take advantage of indexes while the EF "cast(charindex" rules out the use of any indexes on the columns involved. (thus EF will make "DBAs run off screaming" while L2S won't in this case)(from cust in nd.Customers where cust.CompanyName.StartsWith("a") select cust).ToList<Customer>();...translates into...SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax], [t0].[PrimaryEmailAddress]FROM [dbo].[Customers] AS [t0]WHERE [t0].[CompanyName] LIKE @p0

#2 unruledboy on 9.22.2008 at 5:14 AM

hi, intersting article. I suggest that you try out the free linqpad util:http://www.linqpad.net/

#3 Julia Lerman on 9.25.2008 at 9:21 AM

LINQPad doesn't support LINQ to Entities, but thanks for the reminder! I hadn't checked recently.

#4 CSIO on 1.08.2010 at 9:17 PM

I do realise this post is rather old, but do hear me out if you may.

I'm in the process of trying to convince my direct superior of adopting ASP.NET MVC with an ORM over the now practically impossible to maintain and version ASP.NET Webforms with SQL 2005/2008 (Business Intelligence heavily used on the same machine).

I'm supposed to propose some sort of scaffolding easier to maintain, distribute and possibly migrate to.

..Been checking out A LOT of info on almost every widely adopted ORM. I concluded that I'm better off sticking with MS (l2s or EF) rather then going against steeper learning curves, unavailable documentation, unclear future, initial and subsequent costs (Castle ActiveRecord, Open Access, Subsonic, NHibernate..)

Then read l2s has its limitations : only (1:1), no auto model refresh and who knows(surely not me) what else.

So I said to myself: "EF's the way"... then bumped into some posts the likes of the above, scaring the cr** outta me..

Finally, the questions:

1) is EF in 3.5 SP1 still plagued by these problems ? rather stupid question, I know, but it's only today that I've actually downloaded the MVC RC2 package and I'm about to jump into edmx's and controllers and helpers and routes, which is all new stuff...

2) has EF in 4.0 undergone some sort of overhaul that includes provider specific flags or whatnot to reduce verbosity and improve efficiency via lady loading adiacent entities?

3) am I getting something wrong in wanting to replace WebForms with MVC + ORM for managing stuff like the following ?

-authentication and role based functionality

-modularity

-basic CRUD with search

-complex CRUD with search, on entity hierarchies (treeview UI)

-complex CRUD with search, on slowly changing self referencing homogeneous hierarchies (treeview UI)

-some AJAX where possible

Thank you in advance for any advance you may give..

Leave a Comment