Почему .ToList () и AsEnumerable () делают мой запрос чувствительным к регистру, а AsQueryable () - нет? - PullRequest
0 голосов
/ 01 мая 2018

В моем приложении реализован плагин typeahead для автоматического заполнения форм.

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

пример: тип "Кевин С" предлагает Кевина Смита, но тип "Кевин С" ничего не предлагает.

Код API

// GET: /api/authors
public IHttpActionResult GetAuthors(string query = null)
{
    var authorsQuery = _context.Authors.ToList().Select(Mapper.Map<Author, AuthorDto>);

    if (!String.IsNullOrWhiteSpace(query))
        authorsQuery = authorsQuery.Where(c => c.Name.Contains(query));

    return Ok(authorsQuery);
}

Я думал, что это как-то связано с выполнением .ToList () перед запросом базы данных с моим вызовом .Where ().

Я изменил свой код на это, и теперь он работает

// GET: /api/authors
public IHttpActionResult GetAuthors(string query = null)
{
    var authorsQuery = _context.Authors.AsQueryable();

    if (!String.IsNullOrWhiteSpace(query))
        authorsQuery = authorsQuery.Where(c => c.Name.Contains(query));

    var authorsDto = authorsQuery.ToList().Select(Mapper.Map<Author, AuthorDto>);
    return Ok(authorsDto);
}

поэтому при вводе «kevin s» typeahead предлагает «Kevin Smith»

Я пытался использовать AsEnumerable вместо AsQueryable (), и он имел тот же эффект, что и исходный код

почему он работает с AsQuerable, а не с другими? это связано с выполнением запроса?

1 Ответ

0 голосов
/ 01 мая 2018

Я думал, что это как-то связано с выполнением .ToList () перед запросом базы данных с моим вызовом .Where ().

Ты прав. С .AsQueryable() ваше c => c.Name.Contains(query) является деревом выражений . Это означает, что он не переведен в код MSIL, который выполняет то, что вы написали, но он переведен в описание того, что вы написали. Entity Framework может использовать это для перевода его в SQL, а в SQL это может быть без учета регистра, даже если это будет чувствительно к регистру в обычном коде C #.

.Where разрешается до Queryable.Where.

Я пытался использовать AsEnumerable вместо AsQueryable (), и он имел тот же эффект, что и исходный код

С .AsEnumerable(), даже если ваш запрос выполняется не сразу, c => c.Name.Contains(query) скомпилирован в обычный код C #.

Это потому, что Queryable.Where нельзя использовать (у вас нет IQueryable<T>), а вместо него используется Enumerable.Where. Последний не принимает деревья выражений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...