【发布时间】:2019-06-13 17:48:50
【问题描述】:
搜索词来自 UI 以搜索表的实体。这些搜索结果在 UI 中的显示顺序如下:
- 第一:完全匹配
- 第二:从那个词开始
- 第三个:包含该词的一个词
- Forth:以那个词结束
- 第五:包含任何事物中的术语
所以我首先从 DB 中获取实体:
result = entities.Where(e => e.Name.Contains(searchTerm)).ToList();
然后我在内存中重新排列它们:
var sortedEntities = result.Where(e => e.Name.ToLower() == searchTerm.ToLower())
.Union(result.Where(e => e.Name.StartsWith(searchTerm, StringComparison.OrdinalIgnoreCase)))
.Union(result.Where(e => e.Name.Contains($" {searchTerm} ")))
.Union(result.Where(e => e.Name.EndsWith(searchTerm, StringComparison.OrdinalIgnoreCase)))
.Union(result.Where(e => e.Name.Contains(searchTerm)));
在我添加分页之前它工作正常。现在,如果完全匹配在第 2 页(来自 DB 的数据中),它将不会首先显示。
我能想到的唯一解决方案是分离请求(在这种情况下是 5 个请求)并手动跟踪页面大小。我的问题是,有没有办法告诉 DB 尊重该顺序并在一次 DB 行程中获取排序数据?
【问题讨论】:
-
请提供您的分页代码,目前无法使用。
-
entities.Where(e => e.Name.Contains(searchTerm)).Skip((pageNumber - 1) * pageSize) .Take(pageSize).ToList(); -
一个主要问题是,由于 StringComparison.OrdinalIgnoreCase 您正在使用不受支持的字符串方法,这使得 EF-core 自动切换到客户端评估。您可能不需要此比较,因为数据库排序规则可能不区分大小写。请先检查一下,因为这对您的问题的可能解决方案很重要。
-
@Gert Arnold - 我将
Unions 移至请求IQueryable并删除了StringComparison,看来它正在工作。非常感谢。 -
然后您可以将
Unions转换为OrderByDescending/ThenByDescending子句以获得最佳匹配。
标签: sql asp.net entity-framework linq entity-framework-core