如何向SQL Server发出LINQ查询以检查列值是否以单词开头?

时间:2017-01-23 14:38:04

标签: c# sql-server linq

我已经有了这个

        if (options.English != null) query = query
            .Where(w => w.English.Contains(options.English));

我想要做的是扩展这个(可能还有另一个if子句),以便在以下情况下:

  • 用户输入^abc然后我的查询将检查单词是否以“abc”开头。
  • 用户abc然后检查该列是否包含“abc”

我正在使用SQL Server后端数据库。任何人都可以给我一个关于如何实现这个功能的建议。

3 个答案:

答案 0 :(得分:3)

假设您正在使用Entity Framework,您可以使用StartsWith()EndsWith()方法,以获得与Contains()相同的结果,但仅限于字符串的开头或结尾。它会为你生成代码。

然后只需在代码中创建条件语句,以确定应该使用哪种方法。

一些建议:

EF Core可能存在一个错误,它将StartsWith("string")转换为LIKE "string%",这可能会产生包含字符串的错误结果,包含通配符,例如“_”。

所以我建议你在EF Core中使用普通的SQL,并且假设你使用SQL Server作为DBMS,那么查询:

if (searchText.StartsWith("^"))
{
    var result = query.FromSql($"SELECT something FROM table WHERE PATINDEX({searchText.Substring(1)}, something) = 1");
}
else
{
    var result = query.FromSql($"SELECT * FROM table WHERE PATINDEX({searchText.Substring(1)}, something ) <> 0");
}

使用PATINDEX(),即使您的模式字符串包含通配符,您也会得到正确的结果 - 依靠StartsWith()EndsWith()来逃避潜在的错误,以生成正确的SQL代码。

但这只适用于EF Core,EF 6就像其他人回答的方式一样魅力:)

答案 1 :(得分:2)

您可以将该选项放在条件语句中:

IQueryable<Whatever> query = ...;

if (searchText.StartsWith("^"))
{
    query = query.Where(w => w.English.StartsWith(searchText.Substring(1)));
}
else
{
    query = query.Where(w => w.English.Contains(searchText));
}

你也可以内联进行相同的比较,但是如果它甚至有用的话,那会产生非常难看的SQL:

query = query.Where(w => 
        searchText.StartsWith("^")
            ? w.English.StartsWith(searchText.Substring(1))
            : w.English.Contains(searchText));

请注意,您通常不希望使用SQL搜索文本,因为这会导致用户体验非常糟糕。看一下全文索引。

答案 2 :(得分:1)

if (options.English != null) 
{
    bool englishStartsWith = options.English.StartsWith("^");
    if(englishStartsWith)
    {
       query = query.Where(w => w.English.StartsWith(options.English.Substring(1)));
    }
    else
    {
       query = query.Where(w => w.English.Contains(options.English));
    }
}