You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:57:57