LINQ表达式未转换为SQL

MaL*_*223 4 c# linq entity-framework entity-framework-core .net-core

我正在尝试从LINQ实现一个编译的SQL查询,它将检查query数据库中是否有三列的子串(不区分大小写).

我正在使用.NET Core 1.1

我想出的查询如下:

users.Select(u => new
  {
    User = u,
    query = u.FirstName.ToLower() + u.LastName.ToLower() + u.Email.ToLower()
  }).Where(x => x.query.Contains(query))
Run Code Online (Sandbox Code Playgroud)

但是在查看调试信息时,我收到了这个警告:

LINQ表达式'(([u] .FirstName.ToLower()+ [u] .LastName.ToLower())+ [u] .Email.ToLower()).包含(__ query_0)'无法翻译,将会是在当地评估.

我试过的第二个查询:

 users.Where(x => u.FirstName.ToLower().Contains(query) || u.LastName.ToLower().Contains(query) || u.Email.ToLower().Contains(query))
Run Code Online (Sandbox Code Playgroud)

但它给了我完全相同的警告.

为什么会这样?我正在寻找类似的东西:

SELECT * FROM USERS WHERE FirstName LIKE query OR LastName LIKE query OR Email LIKE query
Run Code Online (Sandbox Code Playgroud)

UPDATE

我又做了一个实验:

    users.Where(u =>
    u.FirstName.Contains(query) ||
    u.LastName.Contains(query) ||
    u.Email.Contains(query));
Run Code Online (Sandbox Code Playgroud)

这也导致了

LINQ表达式'(([u] .FirstName.Contains(__ query_0)OrElse [u] .LastName.Contains(__ query_1))OrElse [u] .Email.Contains(__ query_2))'无法翻译,将在本地进行评估.

Mag*_*nus 6

这是因为.ToLower()并且.Contains()是字符串类中的函数,并且不能由linq提供程序转换为SQL.
所有查询(除非明确指定)都将遵循数据库排序规则,如果是CI,则为Case Insensitive并且您不需要.ToLower().至于.Contains()你需要使用实体功能Like.

users.Where(u =>
    EF.Functions.Like(u.FirstName, "%" + query + "%") ||
    EF.Functions.Like(u.LastName, "%" + query + "%") ||
    EF.Functions.Like(u.Email, "%" + query + "%"));
Run Code Online (Sandbox Code Playgroud)

但是,这似乎是在EF核心2.0中添加的.对于1.1我不认为有任何方法可以做到这一点.我建议直接跳过EF并编写普通的旧SQL.

  • 我认为它被添加到Core 2.0.与EF 6相比,EF Core中缺少许多功能.有关详细信息,请参阅https://blogs.msmvps.com/ricardoperes/2016/09/05/missing-features-in-entity-framework-core/. (2认同)