Объяснение
У меня была такая же проблема, и я выяснил, почему это происходит. Запуск SQL Profiler Я увидел, что операторы WHERE , сгенерированные из LINQ to SQL , сильно отличаются в каждом случае.
.Where(z => z.Province.Contains(provinceName))
будет отображаться в SQL как:
WHERE [Province] LIKE N'%%'
Как вы уже убедились, LIKE '%%'
будет соответствовать любым ненулевым результатам.
.
Однако
.Where(z => z.Province.ToLower().Contains(provinceName.ToLower()))
будет отображаться в SQL как:
WHERE ( CAST( CHARINDEX(LOWER(N''), LOWER([Province])) AS int)) > 0
Это очень отличается от LIKE '%%'
. SQL по сути ищет, какой символ string.Empty
находится в строке Province . Результат CHARINDEX
в пустой строке равен 0, поэтому никаких результатов не возвращается.
.
Обходной путь
Это немного глупо, но это сработает. Вызывайте .ToLower()
только если строка не пустая. Следующий код является примером того, что должно работать для вас.
public IQueryable<CityPM> GetCities(string provinceName)
{
var lowerProvinceName = String.IsNullOrEmpty(provinceName) ? string.Empty : provinceName.ToLower();
return this.ObjectContext.ZipCodes.Where(z => z.Province.ToLower().Contains(lowerProvinceName))
.GroupBy(z => z.City)
.Select(g => g.FirstOrDefault())
.Select(zc => new CityPM() { ID = zc.ID, Name = zc.City });
}
Структурируя ваш код следующим образом, LINQ to SQL будет отображаться как LIKE '%%'
, если ProvinceName - пустая строка, в противном случае он будет отображаться как CHARINDEX
. Также помогает, если передан нуль.