首页 > 解决方案 > LINQ - 按 StartsWith 排序,然后包含(自动完成)

问题描述

我正在实现一个autocomplete功能,我需要根据用户输入过滤 SQL 表。

因此,要求是过滤应该开始(sort)结果的记录StartsWith,然后Contains

样本数据:

Dotnet 开发人员
Azure 管理员
Microsoft Azure
Azure DevOps
UX 开发人员
IOT Azure

如果我开始输入Azu,那么它应该按以下顺序显示结果。

Az re 管理员
Az re DevOps
Microsoft Az re
IOT Azu re

这意味着,我们正在寻找startswith逻辑然后是contains逻辑的结果。

目前,我尝试了两种方法,但没有奏效。

第一种方法:

dbContext.dbTable.Select(h => h.FieldName.ToLowerInvariant()).Where(e => e.Contains(text)).OrderBy(s => s).Distinct().Take(count).ToList();  

第二种方法:

dbContext.dbTable.Where(e => e.FieldName.Contains(text)).OrderBy(h => h.FieldName.IndexOf(text)).ThenBy(c => c.FieldName.Length).Select(p => p.FieldName).Distinct().Take(count).ToList();  

如果可能的话,谁能指导我?

标签: c#.netentity-frameworklinq

解决方案


您的主要问题是需求或对需求的理解。

过滤操作:
Reduce(=filter) 基于布尔表达式的结果 其中:
true ==> 显示结果
false==>显示。
它是在 linq 中通过 Where(...) 子句实现的。

在您的情况下,要求是包含text.

.Where(e => e.Contains(text))

排序操作:
给定一个结果列表,决定它们的顺序。您的要求是首先查看 Start by 的值text
换句话说,就是按照这个规则来排序

String.StartsWith返回一个布尔值。
在布尔值上运行 linq OrderBy,按顺序对它们排序,false然后按true. 这是因为 OrderBy 默认排序是升序的,并且false算作“小于” true。(合理的决定)

所以,知道了这一点,你可以通过运行来实现你想要的

.OrderByDescending(s => s.StartsWith(text))

全逻辑:

dbContext.dbTable
         .Select(h => h.FieldName.ToLowerInvariant())
         .Where(e => e.Contains(text)) // filter
         .Distinct() // more filtering
         .OrderByDescending(s => s.StartsWith(text)) // sort 
         .Take(count)
         .ToList();  

推荐阅读