实体框架对字符串列表的模糊搜索

时间:2021-07-01 20:10:15

标签: string list entity-framework-core fuzzy-search

EntityFrameworkCore 3.1.14

所以我希望实现一个搜索,您可以在其中向搜索添加多个不同的元素,这将从数据库中提取相关数据(包括搜索参数列表)。

我对 EF 还很陌生,但在这方面找不到任何东西..

要求是这样的:

  1. 如果列表为空 - 不要过滤(可能还有其他搜索参数)
  2. 如果列表包含一些字符串,则进行模糊搜索 - 即 string.Contains(string2)

它适用于代码 - 例如

            var list = new List<string> { "aaa", "bbb" };
            var a = new List<string> { "a" };
            var c = new List<string> { "c" };
            var ab = list.Any(listString => a.Any(aString => listString.Contains(aString))); //returns true
            var ac = list.Any(listString => c.Any(cString => listString.Contains(cString))); //returns false

但是,它在 entityframework 中不起作用..我尝试使用以下(一次只有 1 行在 WHERE 中 - 搜索结果在行的末尾)

            var data = context.Meals
                .Where(x =>
                    (!descriptions.Any() || x.Ingredients.Any(db => descriptions.Any(input => input.Contains(db.Description))))  --FAIL
                    (!descriptions.Any() || x.Ingredients.Any(db => descriptions.Any(input => db.Description.Contains(input))))  --FAIL
                    (!descriptions.Any() || descriptions.Any(input => x.Ingredients.Any(db => db.Description.Contains(input))))  --FAIL
                    (!descriptions.Any() || descriptions.Any(input => x.Ingredients.Any(db => input.Contains(db.Description))))  --FAIL


                    (!descriptions.Any() || x.Ingredients.Any(db => db.Description.Contains(descriptions.First())))              --PASS - but restricted to using .First() 
                    (!descriptions.Any() || x.Ingredients.Any(db => descriptions.Contains(db.Description)))                      --PASS - but no fuzzy logic 
                    ).ToList();

错误信息:

LINQ 表达式...无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案 - 即遍历 EF 之外的字符串列表,并为每个元素添加一个新的 where 子句到 EF 对象..

然而,这个修复似乎更像是一种解决方法,而不是在 2 组字符串上使用模糊搜索的正确实现

            var data = context.Meals;
            if(descriptions.Any()){
                descriptions.ForEach(input => data = data.Where(x => x.Any(db => db.Ingredient.Contains(input))))
            }
            return data.ToList();