OData案例Web API中的In-Sensitive过滤?

时间:2017-11-01 12:52:58

标签: sql entity-framework azure asp.net-web-api odata

默认情况下,ODataController执行区分大小写的搜索。我们如何扩展此行为以执行不区分大小写的搜索。

public class NammaODataController : ODataController
{

    [EnableQuery]
    public IQueryable<FD> GetFD(ODataQueryOptions qo)
    {
        return _ctx.FDs.AsQueryAble();
        //EF takes care to apply odata query operators internally 
        //after control passes from action
    }
}
  

我提到this SO似乎我们可以利用表达式树,但是在   哪个可扩展点?

有什么办法可以拦截查询并自定义EF / Web Api piplelie来实现这个目标吗?

  

以下是一个例子:/ FD?$ filter = tolower(Pr_Name)eq tolower('TAMARA') -   这应该归还所有名为'Tamara'的人(案例   麻木不仁,可能是'TAMARA','tamara','Tamara'等。希望这会   帮助,提出我的观点。

修改

  

ODATA Web API queries中的区分大小写与SQL排序无关。这是Microsoft OData框架的一个问题。

  

使用substringof运算符

void Main()
{
    var lower = _ctx.FD
    .Where(sv => sv.Pr_Name.Contains("tamara"))
    .Take(1)
    .ToList();
    Console.WriteLine("LOWER CASE AZURE SQL OUTPUT");
    Console.WriteLine(lower);

    Console.WriteLine("UPPER CASE AZURE SQL OUTPUT");
    var upper = _ctx.FD
    .Where(sv => sv.Pr_Name.Contains("TAMARA"))
    .Take(1)
    .ToList();
    Console.WriteLine(upper);
}

enter image description here

  

使用eq运算符

void Main()
{
    var lower = FD
        .Where(sv => sv.Pr_Name == tamara A TOPOLESKI")
        .Take(1)
        .ToList();
    Console.WriteLine("LOWER CASE AZURE SQL OUTPUT");
    Console.WriteLine(lower);

    Console.WriteLine("UPPER CASE AZURE SQL OUTPUT");
    var upper = FD
        .Where(sv => sv.Pr_Name == "TAMARA TOPOLESKI")
        .Take(1)
        .ToList();
    Console.WriteLine(upper);
}

enter image description here

1 个答案:

答案 0 :(得分:1)

修改

你是对的,问题与你的整理无关。它与您正在使用的odata表达式有关。在您更新的测试查询中,您使用的Contains会在搜索值的任意一端被翻译成带有通配符(任意字符串为零或多个字符)的LIKE。但是,在odata表达式中,您使用的是eq,它将被转换为EF表达式中的=,然后再次转换为SQL查询。由于您在输出中显示的Pr_Name值不完全等于"Tamara"但包含"Tamara",因此odata查询不会带回任何数据。

你需要的是odata过滤器表达式substringof,它将由EF转换为Contains,在sql中将其翻译为LIKE,并在搜索值的任一侧使用通配符。

/FD?$filter=substringof(Pr_Name,'tamara')

有关更多过滤器表达式,请参阅Using Filter Expressions

如评论中所述@ThomasKoelle,这与列的整理有关。 OData管道(您已在上面定义)使用Entity Framework将传入的表达式转换为数据库的查询。所以OData表达式与它无关,也没有构建的EF查询。

如果您使用区分大小写的排序规则,那么您必须将所有搜索字词和搜索列放在相同的情况下,这对性能非常不利,因为这些搜索条款不会是SARGable。

对于大多数DBMS,列的排序规则继承自数据库的默认排序规则,该排序规则从实例默认排序规则继承。您可以在每个级别覆盖,但必须在定义实例(模式/数据库)时明确完成。