Domanda

Say I have an EF query like this:

Orders.Where(z => z.OrderDesc == "SOME VALUE")

This works great and generates a query like this:

SELECT [Extent1].[OrderDesc] AS [OrderDesc]
       [Extent1].[OtherColumns] AS [OtherColumns]
FROM   [dbo].[Order] AS [Extent1]
WHERE  'SOME VALUE' = [Extent1].[OrderDesc]

However if you change the query to this:

Orders.Where(z => z.OrderDesc.ToUpper() == "SOME VALUE")

Then your result is this:

SELECT [Extent1].[OrderDesc] AS [OrderDesc]
       [Extent1].[OtherColumns] AS [OtherColumns]
FROM   [dbo].[Order] AS [Extent1]
WHERE  N'SOME VALUE' = (UPPER([Extent1].[OrderDesc]))

Note that 'SOME VALUE' now has an N in front of it. This causes a severe performance problem.

So, why does EF convert to Unicode when ToUpper is called?

OrderDesc is a varchar(200) and UPPER can return a varchar. Why would doing a ToUpper cause EF to want to switch to Unicode?

NOTE: I get that SQL Server is typically case insensitive so there is little point to calling the ToUpper for a compare. But I still want to know why EF does this.

È stato utile?

Soluzione

As far as I can understand from the EF source code, it depends on the entity's property whether or not a Unicode argument is generated. Here "property" refers to the property in the mapping model. Each property has an EDM type (Entity Data Model), which contains more meta data than a .Net type, one of which is the type of the mapped column in the database, including Unicode.

But a method call, ToUpper in this case, breaks the direct link with the property. After all, a method call could have multiple arguments, so it's probably too complex (or: deemed not worth the effort) to infer a matching argument type wrt. Unicode. So EF seems to err on the side of caution and chooses Unicode.

However, apart from these somewhat speculative considerations, in your case it is irrelevant whether or not the parameter is Unicode. By filtering on a processed value, not the original value, the query optimizer can't pick an index anyway. The filter expression is not sargable.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top