Search code examples
linqentity-framework-corenpgsql

Cannot filter data on server using Linq, EF Core, Npgsql, Postgres


I tried to google a solution, as well as I read documentation. So, I have trouble with filtering my entity this way:

// Raises the exception
MyUser myUser = _sqlContext.MyUsers
    .Where(user => user.UserLogin.ToLower() == userLogin.ToLower())
    .ToList()
    .FirstOrDefault();

// Raises the exception
MyUser myUser = _sqlContext.MyUsers
    .Where(user => user.UserLogin.ToLower() == userLogin.ToLower())
    .ToList()
    .FirstOrDefault();

// Raises the exception, too
MyUser myUser = _sqlContext.MyUsers
    .Where(user => user.UserLogin == userLogin)
    .FirstOrDefault();

// Raises the exception, too
MyUser myUser = _sqlContext.MyUsers
    .FirstOrDefault(user => user.UserLogin == userLogin);

I receive the following exception:

The LINQ expression 'DbSet .Where(p => p.UserLogin.ToLower() == __ToLower_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

The list of users can be really big, so this in no option to call ToList() before Where() to force client-side filtering. In contrary, I need EF to build a query with WHERE, and return to client only filtered values.

My application uses ASP.NET Core 3.1 as well as EF Core 3.1.5. It doesn't work too if I remove ToLower(). How can I make this work?

UPD: The problem is in custom getter/setter of user.UserLogin. Here Is the part of model:

public class MyUser
{
    internal string _userLogin { get; set; }

    public string UserLogin
    {
        get => _userLogin;
        set => _userLogin = value.ToLower();
    }
}

Solution

  • I had to delete custom getter and setter as well as _userLogin field. So, the conclusion - there should be nothing except simple properties or fields inside Where or First(OrDefault) call.