How can I build in wildcards to my LINQ To SQL lambda expression?
This is what I have currently:
var query = from log in context.Logs select log;
foreach (string filter in CustomReport.ExtColsToFilter)
{
string tempFilter = filter;
query = query.Where(Log => Log.FormattedMessage.Contains(tempFilter));
}
This works fine up until I try and pass wildcards in the filter string. I'm experimenting with SqlMethods.Like()
but to no avail.
The filters above look like this: "<key>NID</key><value>mcass</value>"
.
I'd like to be able to pass filters like this: "<key>NID</key><value>%m%</value>"
String.Contains
is actually implemented as a LIKE
expression in LINQ to SQL, so these queries would be equivalent:
query = query.Where(Log => Log.FormattedMessage.Contains("m"));
query = query.Where(Log => SqlMethods.Like(Log.FormattedMessage, "%m%"));
However, with SqlMethods.Like
, you can specify more complex patterns, such as "%m%a%"
. Works fine for me. You can't really see the difference from inside visual studio, because the expression to be matched against is put inside a parameter in the T-SQL.
If you were to log the SQL query in a profiler, it would look something like this:
exec sp_executesql N'SELECT [t0].[ID], [t0].[FormattedMessage]
FROM [dbo].[Log] AS [t0]
WHERE [t0].[FormattedMessage] LIKE @p0',N'@p0 nvarchar(5)',@p0=N'%m%a%'
Not relevant to the question per se, but String.StartsWith
and String.EndsWidth
also translate to a SQL LIKE
, with slightly different patterns of course.
The wildcard is such as, m*, so anything with an m, for the wildcard you can ask if it .Contains(m); and it will get anything containing 'm'.
If you need wildcard in the sense of ALL the results from that table, just use
query.ToList();
You now have the entire list of Logs.
Hope that helps.