为什么.ToList()和AsEnumerable()使我的查询区分大小写,但AsQueryable()不是?

时间:2018-05-01 19:13:28

标签: c# asp.net entity-framework linq

我已经在我的应用程序上实现了twitter的typeahead插件,用于表单自动完成。

当查询数据库中与输入框中输入的名称匹配时,它只匹配区分大小写的名称,但是typeahead应该匹配不区分大小写。

示例:“凯文S”打造了凯文史密斯,但“凯文斯”的先例表明什么都没有。

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);
}

我认为在使用.Where()调用查询数据库之前,它与.ToList()执行有关。

我将代码更改为此代码现在可以正常运行

// 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 :(得分:2)

  

我认为在使用.Where()调用查询数据库之前,它与.ToList()执行有关。

你是对的。使用.AsQueryable(),您的c => c.Name.Contains(query)表达式树。这意味着它没有被转换为运行你所写内容的MSIL代码,但它被翻译成你所写内容的描述。实体框架可以使用它将其转换为SQL,而在SQL中,即使它在普通的C#代码中区分大小写,也可能不区分大小写。

.Where解析为Queryable.Where

  

我尝试使用AsEnumerable而不是AsQueryable(),它与原始代码具有相同的效果

使用.AsEnumerable(),即使您的查询未立即执行,c => c.Name.Contains(query) 也会编译为常规C#代码。

这是因为无法使用Queryable.Where(您没有IQueryable<T>),而是使用Enumerable.Where。后者不接受表达树。