如何使用 Linq where 条件检查字符串列表是不是包含任何字符串
Posted
技术标签:
【中文标题】如何使用 Linq where 条件检查字符串列表是不是包含任何字符串【英文标题】:How to use Linq where condition to check if a list of strings contains any string如何使用 Linq where 条件检查字符串列表是否包含任何字符串 【发布时间】:2021-12-11 15:22:48 【问题描述】:我有一个这样的 LINQ 查询:
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)));
结果是这样的:
User Id | Username | RoleNames
1 | Matt | [User, Admin]
2 | Jennifer | [User]
3 | John | []
但是
x.RoleNames.Any(r => r.Contains(searchText))
不工作,导致 InvalidOperationException:无法翻译 LINQ 表达式“...”。
我想传入一个 searchText 来搜索“用户名”和“角色名称”列。 例如。如果我传入 searchText = 'Jen' 它将返回用户 ID 2,如果我传入 searchText = 'user' 它将返回用户 ID 1 和 2。
任何帮助将不胜感激。
【问题讨论】:
你有导航属性User.Roles
,或者类似的吗?
我猜Users
不是一个简单的IEnumerable
,_context
是一个DbContext
,而您正在使用像实体框架这样的ORM。问题是,您的 ORM 不知道如何将您的 Lambda 表达式转换为数据库查询,所以这实际上不是 Linq 问题。
您使用的是什么 LINQ:LINQ to Objects / SQL / EF 6.x / EF Core 2.0 / 2.1 / 3.x / 5.x / 6.x?什么数据库提供商?
使用LINQKit,您可以使用 Predicate Builder 构建可翻译的表达式。
@NetMage,这里没有任何帮助。自定义投影使得在谓词中重用集合变得困难。
【参考方案1】:
虽然理论上可以将此条件转换为 SQL,但您的 EF Core 版本不支持。考虑在定义自定义投影之前进行过滤:
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()
;
【讨论】:
【参考方案2】:这可能不是你现在想要的答案,但你可能会在以后回顾它并认为它是正确的答案。
您的 ORM(可能是实体框架)无法将您的 Linq 表达式转换为查询。如果您的项目将有一个小型数据库并且您不需要查询来很好地执行,那么请调整您的表达式,以便 ORM 可以生成一个正常运行的查询,尽管不是最佳的。
如果数据将成为您项目的重要组成部分,那么切换到像 Dapper 这样的轻量级 ORM 并学习数据库的查询语言。使用该查询语言编写最优的参数化查询并产生长期效益。
【讨论】:
以上是关于如何使用 Linq where 条件检查字符串列表是不是包含任何字符串的主要内容,如果未能解决你的问题,请参考以下文章
C# LINQ 与两个不同数据集上的条件 where 子句连接