Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to Sql any keyword search query

Tags:

c#

linq-to-sql

I have a case in my application where the user can search for a list of terms. The search needs to make three passes in the following order:

  • One for an exact match of what they entered. Done, easy.
  • One where all the words (individually) match. Done, also easy.
  • One where any of the words match...how?

Essentially, how do I, in Linq to Sql, tell it to do this:

select * from stuff s where s.Title like '%blah%' || s.Title like '%woo&' || s.Title like '%fghwgads%' || s.Title like...

And so on?

like image 872
Dusda Avatar asked Jan 06 '10 02:01

Dusda


People also ask

How does a LINQ query transform to a SQL query?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

What is any () in LINQ?

The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.

How do I get SQL query from LINQ in Visual Studio?

You can get same generated SQL query manually by calling ToString: string sql = committeeMember. ToString();

Is LINQ to SQL still used?

LINQ to SQL was the first object-relational mapping technology released by Microsoft. It works well in basic scenarios and continues to be supported in Visual Studio, but it's no longer under active development.


1 Answers

This might be a tough one... I think you'd have to write your own operator.

(Update: Yep, I tested it, it works.)

public static class QueryExtensions
{
    public static IQueryable<TEntity> LikeAny<TEntity>(
        this IQueryable<TEntity> query,
        Expression<Func<TEntity, string>> selector,
        IEnumerable<string> values)
    {
        if (selector == null)
        {
            throw new ArgumentNullException("selector");
        }
        if (values == null)
        {
            throw new ArgumentNullException("values");
        }
        if (!values.Any())
        {
            return query;
        }
        var p = selector.Parameters.Single();
        var conditions = values.Select(v =>
            (Expression)Expression.Call(typeof(SqlMethods), "Like", null,
                selector.Body, Expression.Constant("%" + v + "%")));
        var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c));
        return query.Where(Expression.Lambda<Func<TEntity, bool>>(body, p));
    }
}

Then you could call this with:

string[] terms = new string[] { "blah", "woo", "fghwgads" };
var results = stuff.LikeAny(s => s.Title, terms);

P.S. You'll need to add the System.Linq.Expressions and System.Data.Linq.SqlClient namespaces to your namespaces for the QueryExtensions class.

like image 122
Aaronaught Avatar answered Nov 13 '22 13:11

Aaronaught