一个更简单、更正确的解决方案(然后是 leppie's):
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;
}
只要partName
是字符串(或字符串的 SQL 等效项),这将起作用。
需要注意的重要一点partName.Contains(qs)
是不同于query.Contains(partName)
.
使用partName.Contains(qs)
,partName
搜索任何出现的qs
. 生成的 SQL 将是等效的(其中 <qs> 是 的值qs
):
select * from Parts where partName like '%<qs>%';
还要注意的是StartsWith
和EndsWith
类似于Contains
但在特定位置查找字符串。
query.Contains(partName)
与 SQLin
命令相同。生成的 SQL 将等效于(其中 <query0> 是 的值query[0]
,<query1> 是 的值query[1]
,<queryN> 是查询数组中的最后一个值):
select * from Parts where partName in ( <query0>, <query1>, ..., <queryN> );
更新:同样重要的是要注意,leppie 的答案在将通配符添加到like语句
之前不会转义它们。这不是解决方案的问题,因为 Linq 将在发送查询之前对其进行转义。解决方案的转义版本是:Contains
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;
}
您不必担心 ' 因为 Linq 会为您避免这种情况。