在Linq / ODataController

时间:2015-12-17 12:53:51

标签: c# asp.net sql-server linq odata

我正在开发一个通过OData提供数据的应用程序。我正在使用ASP.Net和ODataControllers通过EF查询 - 数据由SQLServer数据库支持。

在可视化此数据的前端网站上,用户可以搜索结果 - 在前端动态创建$ filter并发送OData请求(允许服务器端过滤)。

在支持最终通过OData提供的数据的数据库表上,启用了全文搜索,但它出现在管道OData过滤器中 - > Linq查询 - > SQL查询,使用LIKE搜索而不是全文Contains()方法。

有没有人知道如何以合理优雅的方式使用全文功能?

据推测,我可以使用自定义IODataPathHandler和/或IODataPathTemplateHandler和/或其他一些东西来扼杀管道中的点,但我宁愿尽量避免如果可能的话。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

为此目的使用interceptor和自定义EnableQueryAttribute

  1. 按照文章中的说明定义FtsInterceptor类,并将其添加到您的上下文中 - DbInterception.Add(new FtsInterceptor())
  2. 定义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);
        }
    }
    
  3. 在代码中使用该属性:

    [FullTextSearchAttribute]
    public IQueryable<YourDomainClass> Get()
    {
        //Query 
    }