MAUI中用EF查询SQLite表含字符串数组元素的记录
解决MAUI中EF Core SQLite多关键词筛选Product表的问题
问题原因
你之前的代码抛出Cannot compile: Lambda异常,是因为EF Core的SQLite提供程序无法将words.Any(p => e.Description.Contains(p))这类表达式转换为对应的SQL语句——EF Core无法解析本地集合的Any结合Contains的逻辑,生成需要的多个OR LIKE条件。
解决方案:手动构建查询谓词
我们可以通过构建表达式树的方式,手动拼接多个OR条件,让EF Core能正确转换为目标SQL。
方法1:自定义PredicateBuilder构建表达式
首先实现一个简单的PredicateBuilder工具类,用来拼接OR条件:
public static class PredicateBuilder { public static Expression<Func<T, bool>> True<T>() => f => true; public static Expression<Func<T, bool>> False<T>() => f => false; public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); } }
然后在MAUI页面的筛选逻辑中使用:
// 从Entry获取筛选文本,替换为你的Entry控件Text属性 var filterInput = YourEntry.Text?.Trim() ?? string.Empty; // 拆分关键词,过滤空字符串 var keywords = filterInput.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // 初始化查询谓词 var queryPredicate = PredicateBuilder.False<Product>(); foreach (var keyword in keywords) { var currentKeyword = keyword; // 避免闭包捕获变量的问题 queryPredicate = queryPredicate.Or(p => p.Description.Contains(currentKeyword)); } // 处理无关键词的情况:返回所有产品 if (keywords.Length == 0) { queryPredicate = PredicateBuilder.True<Product>(); } // 执行查询 var filteredProducts = dbContext.Product.Where(queryPredicate).ToList();
方法2:使用动态LINQ(需安装NuGet包)
如果你不想自己写表达式树,可以安装System.Linq.Dynamic.Core NuGet包,直接拼接条件字符串:
using System.Linq.Dynamic.Core; // 拆分关键词 var filterInput = YourEntry.Text?.Trim() ?? string.Empty; var keywords = filterInput.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); IQueryable<Product> query = dbContext.Product; if (keywords.Length > 0) { // 构建参数化条件,避免SQL注入 var parameters = keywords.Select((kw, index) => new { Name = $"p{index}", Value = kw }).ToList(); var conditionString = string.Join(" OR ", parameters.Select(p => $"Description.Contains({p.Name})")); query = query.Where(conditionString, parameters.Select(p => p.Value).ToArray()); } var filteredProducts = query.ToList();
说明
- 两种方法最终都会生成你需要的SQL:
select * from Product where Description like '%Tires%' OR Description like '%GoodYear%' - 注意处理空筛选文本的情况,避免生成无效的查询条件
- SQLite默认的
LIKE操作是大小写不敏感的,如果需要大小写敏感,可以在Contains时指定StringComparison.Ordinal,或者修改SQLite的排序规则
内容的提问来源于stack exchange,提问作者Roberto Oropeza
相关产品推荐
相关产品推荐

