2014-01-06 6 views
3

Я запрашиваю базу данных MS SQL с использованием Linq и Entity Framework Code First. Требование состоит в том, чтобы иметь возможность использовать в таблице WHERE SomeColumn LIKE '%sometext'.Как изменить sql, сгенерированный linq-to-entity?

Это, на поверхности, является простым требованием, что может быть достигнуто с помощью простого запроса Linq так:

var results = new List<MyTable>(); 
using(var context = new MyContext()) 
{ 
    results = context.MyTableQueryable 
    .Where(x => x.SomeColumn.EndsWith("sometext")) 
    .ToList(); 
} 
// use results 

Однако, это не было эффективным на практике. Проблема заключается в том, что столбец SomeColumn не является varchar, скорее это char (31). Это означает, что если строка сохраняется в столбце, который меньше 31 символа, тогда в конце строки будут добавлены пробелы, чтобы обеспечить длину 31 символ, и это вызывает фол до запроса .EndsWith().

Я использовал SQL Profiler для поиска точного sql, который был сгенерирован из метода .EndsWith(). Вот что я нашел:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE N'%sometext' 

Так , что интересно. Я не уверен, что означает N до '%sometext'. (Я нагуглить позже.) Но я знаю, что если взять тот же запрос и запустить его в SSMS без N как это:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE '%sometext' 

Тогда запрос отлично работает. Есть ли способ заставить Linq и Entity Framework удалить этот запрос N?

+1

'' N'' в основном означает, что он смотрит на вашу строку как на varchar, что, вероятно, является вашей проблемой. – Kippie

+0

[VARCHAR и NVARCHAR] (http://stackoverflow.com/questions/144283/what-is-the-difference-between-varchar-and-nvarchar). Что касается ошибки, которую вы получаете, это кажется странным, а не проблемой, которую я испытал, но опять же я использую «NVARCHAR» в моих последних базах данных без проблем. – XN16

+0

@ XN16 - Я тоже предпочитаю nvarchar. К сожалению, я не имею права использовать его в этом случае. – quakkels

ответ

2

Пожалуйста, попробуйте это ...

.Where(x => x.SomeColumn.Trim().EndsWith("sometext")) 
+0

oof. Спасибо, это работает. Теперь мне нужно написать метод '.Trim()' в мой генератор дерева выражений тоже .... тьфу. Я надеялся, что смогу этого избежать. :-) – quakkels

+0

@quakkels Спасибо .. –

+0

Для тех, кто заинтересован, это приводит к следующему запросу: 'WHERE LTRIM (RTRIM ([Extent1]. [SomeColumn])) LIKE N '% sometext'' – quakkels

1

Просто разговаривал с моим коллегой, который имел подобную проблему, увидеть, если следующие работы для вас:

[Column(TypeName = "varchar")] 
public string SomeColumn 
{ 
    get; 
    set; 
} 

Видимо установки типа на колонке сопоставление заставит запрос распознать его как VARCHAR, где строка обычно интерпретируется как NVARCHAR.

+0

Является ли это предназначенным для генерации столбца, который является varchar? (Я не могу изменить существующую базу данных.) Или это связано с тем, что EF обрабатывает столбец char (31) как varchar? – quakkels

+0

@quakkels Я считаю, что это второй вариант, он будет рассматривать его как varchar. – XN16

Смежные вопросы