Having trouble getting this to work:
/// <summary>
/// Retrieve search suggestions from previous searches
/// </summary>
public static string[] getSearchSuggestions(int SectionID, string Query)
{
string[] Suggestions;
string[] Words = Query.Split(' ');
using (MainContext db = new MainContext())
{
Suggestions = (from c in db.tblSearches
where c.SectionID == SectionID &&
Words.Any(w => c.Term.Contains(w))
select c.Term).ToArray();
}
return Suggestions;
}
I get:
System.NotSupportedException: Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
I want to return records where the field c.Term
contains any of the words in the Words
array. I would also like to have it ordered by the total number of matches, but that seems really hard to do! I found this MSDN. But I can't get it to work with my query either. Also found this but it's not working.
Contains() is a string method. This method is used to check whether the substring occurs within a given string or not. It returns the boolean value. If substring exists in string or value is the empty string (“”), then it returns True, otherwise returns False.
To check for an element in a string, use the Contains() method. The following is our string array. string[] arr = { "Java", "C++", "Python"}; Now, use Contains() method to find a specific string in the string array.
To check if an array contains a specific element in C#, call Array. Exists() method and pass the array and the predicate that the element is specified element as arguments. If the element is present in the array, Array. Exists() returns true, else it returns false.
The Any method checks whether any of the element in a sequence satisfy a specific condition or not. If any element satisfy the condition, true is returned.
Ok, after plugging away enough at it I realized that the problem wasn't the Any or the Contains. Linq to SQL doesn't like you combining the local sequence (words) with the SQL collection (db.tblSearches). So in order to accomplish this, you have to break it out into 2 separate queries.
public static string[] getSearchSuggestions(int SectionID, string Query)
{
string[] Suggestions;
string[] Words = Query.Split(' ');
using (MainContext db = new MainContext())
{
string[] all = (from c in db.tblSearches
where c.SectionID == SectionID
select c.Term).ToArray();
Suggestions = (from a in all
from w in Words
where a.Contains(w)
select a).Distinct().ToArray();
}
return Suggestions;
}
Keep in mind, that in the second query, the Contains
is case sensitive, so you might have to add a case-insensitive extension method or go old school and kick them .ToUpper()
. I ran this in 4.0 on one of my contexts and it returned all 88 strings correctly (out of a possible 9814). Though it was a thorough PITA. Definite +1 on this question.
Edit:
Added .Distinct()
to the final answer.
First convert your array to a list,
List<string> wordList = Words.ToList();
then change your linq query as follows:
Suggestions = (from c in db.tblSearches
where c.SectionID == SectionID &&
Words.Contains(c.Term)
select c.Term).ToArray();
I think I see your problem though. In your original query you are using c.Term.Contains()... Contains is an extension method that needs to be called on an object that implements Enumerable so you cannot call it on a field you are getting back from your database call. That is why the other user that answered your question said you needed to flip things around in your Contains, because it is never going to let you make that call on c.Terms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With