0

I'm having an issue toLower() in lambda query. I have this code

var filterResult = articleList
                        .Where(m => m.Summary
                            .Contains(filteredModel.Keyword) || m.Body.Contains(filteredModel.Keyword) || m.Headline.Contains(filteredModel.Keyword) 
                            || m.Title.Contains(filteredModel.Keyword))
                        .AsQueryable();

I need to add toLower() method as sql. For example:

var filterResult = articleList
    .Where(m => m.Summary.toLower()
        .Contains(filteredModel.Keyword.toLower()) || m.Body.toLower().Contains(filteredModel.Keyword.toLower()) || m.Headline.toLower().Contains(filteredModel.Keyword.toLower()) 
        || m.Title.toLower().Contains(filteredModel.Keyword.toLower()))
    .AsQueryable();

As above code, lambda doesn't allow to use. I wonder if there is other way to do to achieve this.

Tun
  • 824
  • 3
  • 16
  • 30
  • 2
    What error message do you get? – Mark Byers Aug 08 '12 at 14:43
  • 3
    .toLower() should be .ToLower() – Ral Zarek Aug 08 '12 at 14:45
  • In C# the method is `ToLower()` not `toLower()`, not sure if that is a typo or not, but `ToLower()` should be perfectly legal to use. – NominSim Aug 08 '12 at 14:45
  • @MarkByers He'll get a not supported exception because there is no ToLower method in SQL. What he needs is a case insensitive contains in SQL. – Servy Aug 08 '12 at 14:46
  • 1
    Its probably that EF / Linq2SQL etc can't map the function into the database. If you have a case insensitive collation on your table, you shouldn't need ToLower? – StuartLC Aug 08 '12 at 14:46
  • @nonnb you're right. I used EF ORM before. I got an error this method doesn't allow to use. But I'm working on OpenAccess ORM which allow it to use. – Tun Aug 08 '12 at 15:06

2 Answers2

0

You could achieve the same with

    .Where(m => m.Summary.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Body.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Headline.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 
       || m.Title.IndexOf(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) >= 0 

which I believe should be supported by your Linq provider

You could make this neater as described here by creating an extension method

public static bool Contains(this string source, string toCheck, StringComparison comp) {
  return source.IndexOf(toCheck, comp) >= 0;
}

So you could then do

.Where(m => m.Summary.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Body.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Headline.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
           || m.Title.Contains(filteredModel.Keyword, StringComparison.OrdinalIgnoreCase) 
Community
  • 1
  • 1
AlexC
  • 10,676
  • 4
  • 37
  • 55
0

ToLower should work, try breaking it up into different lines to narrow down which check is failing - remember it won't execute until you actually pull the results down e.g.

var keyword = filteredModel.Keyword.ToLower();
var filterResult = articleList.Where(m => m.Summary.ToLowerInvariant().Contains(keyword));
filterResult = filterResult.Where(m => m.Body.ToLower().Contains(keyword));
filterResult = filterResult.Where(m => m.Headline.ToLower().Contains(keyword));
filterResult = filterResult.Where(m => m.Title.ToLower().Contains(keyword));

Also just an FYI - if your converting to lower case for culture-independant comparison then you should be using ToLowerInvariant...or better yet using ToUpperInvariant as it's more reliable.

Community
  • 1
  • 1
James
  • 80,725
  • 18
  • 167
  • 237