简体   繁体   中英

How to use Linq where condition to check if a list of strings contains any string

I have a LINQ query like this:

var data = from user in _context.Users
           select new
           {
               UserId = user.Id,
               Username = user.UserName,
               RoleNames = (from userRole in _context.UserRoles
                            join role in _context.Roles on userRole.RoleId
                            equals role.Id
                            where userRole.UserId == user.Id
                            select role.Name).ToList()
           };

if (!string.IsNullOrEmpty(searchText))
    data = data.Where(x => x.Username.Contains(searchText) || x.RoleNames.Any(r => r.Contains(searchText)));

The result are something like this:

User Id | Username      | RoleNames
1       | Matt          | [User, Admin]
2       | Jennifer      | [User]
3       | John          | []

But the

x.RoleNames.Any(r => r.Contains(searchText))

is not working, it's causing InvalidOperationException: The LINQ expression '...' could not be translated.

I want to pass in a searchText to search for either "Username" and "RoleNames" columns. Eg if I pass in searchText = 'Jen' it will return User Id 2, and if I pass in searchText = 'user' it will return User Id 1 and 2.

Any help would be appreciated.

This may not be the answer you want now but you'll probably look back on this and see it as the right answer later.

Your ORM (Probably Entity Framework) can't translate your Linq Expressions into a query. If your project will have a small database and you don't need your queries to perform well then, tweak your expression so that the ORM can generate a functioning, albeit sub-optimal, query.

If data will be a significant part of your project then switch to a light ORM like Dapper and learn the query language of your database. Write optimal, parameterised queries in that query language and yield the long term benefits.

While theoretically it is possible to translate this condition to the SQL, your EF Core version do not supports that. Consider to make filter before defining custom projection:

var users = _context.Users.AsQueryable();

if (!string.IsNullOrEmpty(searchText))
    users = users.Where(x => x.Username.Contains(searchText) || x.Roles.Any(r => r.Contains(searchText)));

var data = 
    from user in users
    select new
    {
        UserId = user.Id,
        Username = user.UserName,
        RoleNames = (from userRole in _context.UserRoles
                    join role in _context.Roles on userRole.RoleId
                    equals role.Id
                    where userRole.UserId == user.Id
                    select role.Name).ToList()
    };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM