Более простое и правильное решение (чем у Леппи):
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
):
select * from Parts where partName like '%<qs>%';
Также следует отметить StartsWith
и EndsWith
, которые похожи на Contains
, но ищут строку в определенном месте. 1031 *
query.Contains(partName)
аналогичен команде SQL in
. Результирующий SQL будет эквивалентен (где - значение query[0]
, - значение query[1]
, а - последнее значение в массиве запросов):
select * from Parts where partName in ( <query0>, <query1>, ..., <queryN> );
Обновление:
Также важно отметить, что ответ Леппи не экранирует символы подстановки перед добавлением их в оператор 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;
}
Вам не о чем беспокоиться, поскольку Linq избежит этого за вас.