I have an action which returns JSON to a jQuery datatable. The data returned can be filtered depending on the params passed to it. Here’s the code:
public ActionResult IndexAjaxHandler(jQueryDataTableParamModel parameters) {
var data = _mailingListRep.GetAllWithinAccount();
IEnumerable<MailingList> filtered;
// Filtering - THIS DOES NOT WORK!
if (!string.IsNullOrEmpty(parameters.sSearch)) {
filtered = data.Where(c =>
c.MailingListName.Contains(parameters.sSearch) ||
((c.IsDoubleOptIn) ? "Yes" : "No").Contains(parameters.sSearch, StringComparison.OrdinalIgnoreCase) ||
c.Created.ToString("dd MMM yyyy").Contains(parameters.sSearch) ||
c.ActiveMembers.Count().ToString().Contains(parameters.sSearch) ||
c.AvailableSegments.Count().ToString().Contains(parameters.sSearch)
);
}
else {
filtered = data;
}
// create json object
// return;
}
The problem is this gives me the following error:
Method ‘Boolean Contains(System.String, System.String, System.StringComparison)’ has no supported translation to SQL.
BUT
In the same controller is another action which also returns JSON to a datatable, which uses the exact same filtering method and it works fine!
public ActionResult ViewDeletedAjaxHandler(int id, jQueryDataTableParamModel parameters) {
var list = _mailingListRep.GetByIDWithinAccount(id);
var data = list.DeletedMembers;
IEnumerable<MailingListMember> filtered;
// Filtering - THIS WORKS, NO ERRORS!
if (!string.IsNullOrEmpty(parameters.sSearch)) {
filtered = data.Where(c =>
c.EmailAddress.Contains(parameters.sSearch, StringComparison.OrdinalIgnoreCase) ||
c.UnsubscribedDate.ToString("dd MMM yyyy").Contains(parameters.sSearch, StringComparison.OrdinalIgnoreCase)
);
}
else {
filtered = data;
}
// create json object
// return;
}
Does anyone know why this is?
For reference, Contains(string, comparison) is an extension method:
public static bool Contains(this string source, string toCheck, StringComparison comp) {
return source.IndexOf(toCheck, comp) >= 0;
}
I understand what the error means, it is the fact that the code works in 1 action, but not the other than has me completely confused.
Thanks for any help in advance.
Your first filter that does not work is applied to a
IQueryable<T>and your second that works is applied to anIEnumerable<T>.When applied to an
IQueryable<T>, the filter must be translateable to SQL, whereas when it is used on anIEnumerable<T>the filter is evaluated in memory.To make the first one work, you need to either call
ToList()to force the results into memory before applying the filter, or use the helper methods available from theEntityFunctionsclass.