O EF 4 produz constantes de cadeia UNICODE em SQL, onde o tipo de coluna é varchar. Como evitar?

No meu código eu tenho o seguinte fragment de uma consulta L2E:

where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN") && ol.olstatus == "9" 

Isso se traduz em seguinte fragment SQL:

 WHERE ([Extent8].[ohcustno] = @p__linq__1) AND (''IN'' = [Extent7].[ollastdoctype]) AND (''9'' = [Extent7].[olstatus]) ... 

Em uma determinada input, a consulta é executada 3 segundos. Eu mudo a consulta desta maneira:

 where ol.ordhead.ohcustno == login && (ol.ollastdoctype == "IN" || ol.ollastdoctype == "CR") && ol.olstatus == "9" 

e as alterações SQL resultantes são as seguintes:

 WHERE ([Extent6].[ohcustno] = @p__linq__1) AND ([Extent5].[ollastdoctype] IN (N''IN'',N''CR'')) AND (''9'' = [Extent5].[olstatus]) ... 

Note que, por alguma razão bizarra, o Entity Framework decidiu converter meu IN e CR para unicode. O resultado é que a consulta agora é executada 6 segundos na mesma input. Se eu remover manualmente o prefixo N da cláusula IN e executar novamente a consulta no SSMS, o tempo de execução voltará a 3 segundos. Isto é claro, porque o SQL Server Query Optimizer não pode obter vantagem de um índice porque os tipos comparados são agora diferentes (varchar vs nvarchar)

Alguém pode me explicar por que o Entity Framework de repente decide converter minhas constantes em unicode e como posso evitá-lo?

você pode tentar este método EntityFunction.AsNonUnicode , como segue

 where ol.ordhead.ohcustno == login && (ol.ollastdoctype == EntityFunctions.AsNonUnicode("IN") || ol.ollastdoctype == EntityFunctions.AsNonUnicode("CR")) && ol.olstatus == "9" 

Esta é apenas a última esperança, em seguida é reportar bug para a microsoft.

A solução alternativa EntityFunction.AsNonUnicode é realmente bastante limitada, ela só funciona quando o valor fornecido é um literal ou uma cadeia de caracteres:

System.NotSupportedException: O método ‘System.String AsNonUnicode (System.String)’ só é suportado no LINQ to Entities quando o argumento é uma variável de cadeia ou literal.

Este é um problema sério no EF4.1 e foi documentado aqui também: http://connect.microsoft.com/VisualStudio/feedback/details/650410/entity-framework-contains-still-defaulting-to-unicode-for -varchar-fields

Até que isso seja corrigido no próprio EF, não há solução para interceptar a consulta e replace manualmente a syntax usando algo como EFTraceProvider .

Brutal.

Este problema foi oficialmente resolvido nas versões mais recentes da EF. Você pode definir o tipo de coluna usando DataAnnotations. Espero que isso ajude alguém!

Veja esta resposta: Tipo de Coluna de Anotações de Dados EF

Este foi um problema até o lançamento do ODP.net Beta 2, mas com o lançamento Beta3 do ODP.net 4.112.2.50 este problema foi resolvido.