在LINQ to SQL中使用contains()

a_m*_*m0d 38 c# contains linq-to-sql keyword-search

我正在尝试使用linq-to-sql在应用程序中实现一个非常基本的关键字搜索.我的搜索词是一个字符串数组,每个数组项都是一个单词,我想找到包含搜索词的行.我不介意它们是否包含的不仅仅是搜索条件(最有可能的是它们),但所有搜索条件都必须存在.

理想情况下,我想要类似下面的代码片段,但我知道这不起作用.此外,我在这里看过这个问题,但是这个问题的作者似乎满足于反过来做事(query.Contains(part.partName)),这对我不起作用.

public IQueryable<Part> SearchForParts(string[] query)
{
    return from part in db.Parts
           where part.partName.Contains(query)
           select part;
}
Run Code Online (Sandbox Code Playgroud)

如何重写此查询以便它能够满足我的需求?

lep*_*pie 42

看着其他的尝试让我很难过:(

public IQueryable<Part> SearchForParts(string[] query)
{
  var q = db.Parts.AsQueryable(); 

  foreach (var qs in query)
  { 
    var likestr = string.Format("%{0}%", qs);
    q = q.Where(x => SqlMethods.Like(x.partName, likestr));
  }

  return q;
}
Run Code Online (Sandbox Code Playgroud)

假设:

  • partName看起来像:"ABC 123 XYZ"

  • 查询是{"ABC","123","XY"}


Tri*_*ped 20

一个更简单,更正确的解决方案(然后是leppie):

public IQueryable<Part> SearchForParts(string[] query)
{
    var q = db.Parts.AsQueryable(); 

    foreach (string qs in query)
    {
        q = q.Where(x => x.partName.Contains(qs));
    }

    return q;
}
Run Code Online (Sandbox Code Playgroud)

只要partName是字符串(或字符串的SQL等效项),这将起作用.

需要注意的重要事项partName.Contains(qs)是不同于query.Contains(partName).
partName.Contains(qs),partName搜索任何出现的qs.生成的SQL将是等效的(其中<qs>是值qs):

select * from Parts where partName like '%<qs>%';
Run Code Online (Sandbox Code Playgroud)

另外值得注意的是StartsWith,EndsWith它们类似于Contains但在特定位置查找字符串.

query.Contains(partName)与SQL in命令相同.生成的SQL将等效于(其中<query0>是值query[0],<query1>是值query[1],<queryN>是查询数组中的最后一个值):

select * from Parts where partName in ( <query0>, <query1>, ..., <queryN> );
Run Code Online (Sandbox Code Playgroud)

更新:
同样重要的是要注意,leppie的答案在将它们添加到like语句之前不会转义通配符.这不是Contains解决方案的问题,因为Linq将在发送之前转义查询.SqlMethods.Like解决方案的转义版本将是:

public IQueryable<Part> SearchForParts(string[] query)
{
    var q = db.Parts.AsQueryable(); 

    foreach (var qs in query)
    {
        string escaped_bs = qs.Replace("/", "//"),
            escaped_us = escaped_bs.Replace("_", "/_"),
            escaped_p = escaped_us.Replace("%", "/%"),
            escaped_br = escaped_p.Replace("[", "/["),
            likestr = string.Format("%{0}%", escaped_br);

        q = q.Where(x => SqlMethods.Like(x.partName, likestr, '/'));
    }

    return q;
}
Run Code Online (Sandbox Code Playgroud)

您不必担心'因为Linq会为您逃脱.