我正在开发一个通过OData提供数据的应用程序。我正在使用ASP.Net和ODataControllers通过EF查询 - 数据由SQLServer数据库支持。
在可视化此数据的前端网站上,用户可以搜索结果 - 在前端动态创建$ filter并发送OData请求(允许服务器端过滤)。
在支持最终通过OData提供的数据的数据库表上,启用了全文搜索,但它出现在管道OData过滤器中 - > Linq查询 - > SQL查询,使用LIKE搜索而不是全文Contains()方法。
有没有人知道如何以合理优雅的方式使用全文功能?
据推测,我可以使用自定义IODataPathHandler
和/或IODataPathTemplateHandler
和/或其他一些东西来扼杀管道中的点,但我宁愿尽量避免如果可能的话。
有什么建议吗?
答案 0 :(得分:1)
为此目的使用interceptor和自定义EnableQueryAttribute:
FtsInterceptor
类,并将其添加到您的上下文中 - DbInterception.Add(new FtsInterceptor())
。 定义EnableQueryAttribute
类的子类,并覆盖ApplyQuery
方法,为OData {{3}的所有参数添加 FullTextPrefix ( - FTSPREFIX-)功能:
public class FullTextSearchAttribute : EnableQueryAttribute
{
public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
{
if (queryOptions.Filter == null)
return queryOptions.ApplyTo(queryable);
const string pattern = "contains\\([%20]*[^%27]*[%20]*,[%20]*%27(?<Value>[^%27]*)";
var matchEvaluator = new MatchEvaluator(match =>
{
var value = match.Groups["Value"].Value;
return match.Value.Replace($"%27{value}", $"%27-FTSPREFIX-{value}");
});
var request = new HttpRequestMessage(HttpMethod.Get,
Regex.Replace(queryOptions.Request.RequestUri.AbsoluteUri,
pattern,
matchEvaluator,
RegexOptions.IgnoreCase));
return new ODataQueryOptions(queryOptions.Context, request).ApplyTo(queryable);
}
}
在代码中使用该属性:
[FullTextSearchAttribute]
public IQueryable<YourDomainClass> Get()
{
//Query
}