views:

186

answers:

3

I have a textbox that allows a user to specify a search string, including wild cards, for example:

Joh*
*Johnson
*mit*
*ack*on

Before using LINQ to Entities, I had a stored procedure which took that string as parameter and did:

SELECT * FROM Table WHERE Name LIKE @searchTerm

And then I would just do a String.Replace('*', '%') before passing it in.

Now with LINQ to Entities I am trying to accomplish the same thing. I know there is StartsWith, EndsWith and Contains support, but it won't support it in the way that I need.

I read about "SqlMethods.Like" and tried this:

var people = from t in entities.People
             where SqlMethods.Like(t.Name, searchTerm)
             select new { t.Name };

However I am getting the following exception:

LINQ to Entities does not recognize the method 'Boolean Like(System.String, 
System.String)' method, and this method cannot be translated into a store 
expression.

How would I get this same functionality using LINQ to Entities?

A: 
var people = from t in entities.People
                 where t.Name.ToLower().Contains(searchTerm.ToLower())
                 select new { t.Name };

EDIT- I might be mixing syntax. I usually use extension methods; but contains will work.

Mike M.
Except that contains will automatically wrap the whole search term in wild cards. What if the user wants all people whose name starts with "Mar" Mar*Returned Mary Marissa Omar Jamaraquoui(Names have been changed to protect the innocent)
esac
What is even odder is that it is adding in a '~' as well. For a blank search term, searchTerm is "%". When it queries the database, this is what Contains turns it into: @p__linq__2=N'%~%%'
esac
The ~ is probably being used as an escape character to show that it's looking for strings with the literal "%" within it. If you're going to use Contains (which handles the wild carding) then you can't also try to handle the wild carding.
Tom H.
Since I haven't really used LINQ to SQL... is it smart enough to know whether or not the underlying DB is case sensitive when coming up with its SQL? This more applies to StartsWith, but the .ToLower could kill the use of indexes.
Tom H.
@Tom - You know, I'm not even sure. That's a very good question and I might need to do some playing tonight...
Mike M.
+3  A: 

Well, your choices are:

  • Use Contains. I know you don't like it, but it could probably be made to work.
  • Pick a function from SqlFunctions. They're all supported in L2E.
  • Map your own function.
  • +1 to @Yury for ESQL.
Craig Stuntz
I do not 'dislike' Contains. It doesn't work as intended, see my response below to Mike M. There is nothing in SqlFunctions that will include a LIKE clause. The map your own function is obvious, and is essentially what I was doing anyway, but it seems like this is such a simple ask that it would be supported natively.
esac
Between `Contains`, `StartsWith`, and `EndsWith` you can choose which wildcards you need. I believe that covers all your cases.
Craig Stuntz
+4  A: 

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/6529a35b-6629-44fb-8ea4-3a44d232d6b9/

var people = entities.People.Where("it.Name LIKE @searchTerm", new ObjectParameter("searchTerm", searchTerm));
Yury Tarabanko
eSQL FTW! +1...
Randolpho
Thanks, this did exactly what I needed without a lot of finagling.
esac
You are welcome :)
Yury Tarabanko