0

我在 asp.net core v3.1 中运行它

我的问题类似于这个问题:
How to use Linq to check if a list of strings contains any string in a list

与与第一个答案有关的具体问题,使得

filterTags = ["abc", "cd", "efg"]
var results = db.People
                .Where(p => filterTags.Any(tag => p.Tags.Contains(tag)));

所以基本上说
给我来自所有 People
who's Tags 字段的数据库的结果包含任何 filterTags
其中标签 = 由一堆空格分隔的标签填充的大文本字段

这看起来很简单(尤其是因为之前已经写过)
但我得到了一个错误

System.InvalidOperationException:无法翻译 LINQ 表达式“DbSet .Where(p => __filterTags_0 .Any(tag => p.Tags.Contains(tag)))”。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估

有谁知道这意味着什么或我做错了什么?

4

2 回答 2

1

这对于纯 EF LINQ 是不可能的。您必须创建帮助程序来转换表达式树中的搜索列表。

public static class QueryExtensions
{
    private static MethodInfo _containsMethodInfo = typeof(string).GetMethod("Contains")!;

    public static IQueryable<T> FilterUsingContains<T>(this IQueryable<T> query, Expression<Func<T, string>> prop, IList<string> items)
    {
        if (items.Count == 0)
            return query.Where(e => 1 == 2);

        var param = prop.Parameters[0];

        var predicate = items.Select(i =>
                (Expression)Expression.Call(prop.Body, _containsMethodInfo, Expression.Constant(i, typeof(string))))
            .Aggregate(Expression.OrElse);

        var lambda = Expression.Lambda<Func<T, bool>>(predicate, param);

        return query.Where(lambda);
    }
}

然后你可以在你的查询中使用这个扩展

filterTags = ["abc", "cd", "efg"]
var results = db.People
    .Where(p => p.Tags.AsQueryable().FilterUsingContains(t => t, filterTags).Any());
于 2020-12-08T14:05:53.260 回答
-1

这是一个解决方法:

using System.Linq; 

string[] filterTags = {"abc", "cd", "efg"};
var results = db.People.Where(p => filterTags.Contains(p.Tags)).ToList();
于 2020-12-08T10:54:28.730 回答