First, logically you want Any, not All.
Secondly, this is a bad way to create a query filter. All these operations are sent to the database, and the information to determine which filters should be applied is already local. Explicit connections are also bad (you can use association properties instead).
IQueryable<WidgetHistory> query = db.widgetHistories .Where(ph => ph.contact_dt.Value.Date >= startDate && ph.contact_dt.Value.Date <= endDate); if (!string.IsNullOrEmpty(baanCatFam)) { query = query.Where(ph => ph.baan_cat_family_code == baanCatFam); } if (!string.IsNullOrEmpty(baanCat)) { query = query.Where(ph => ph.baan_cat_code == baanCat); } if (!string.IsNullOrEmpty(baanSubCat)) { query = query.Where(ph => ph.baan_sub_cat_code == baanSubCat); }
Third: the answer to your question.
what causes this error
The LinqToSql query provider cannot translate your local collection into sql. There is only a limited set of scripts where it can translate ... .Where(ph => idList.Contains(ph.Id)) converted to an IN clause with 1 parameter for int in idList.
To get around this limitation, you need to convert the local collection to an expression. Start by converting each item in the collection to a filter expression:
List<Expression<Func<WidgetHistory, bool>>> skuFilters = skuList.Select<string, Expression<Func<WidgetHistory, bool>>>(skuItem => ph => ph.ProductMod.StartsWith(skuItem) ).ToList();
Next, the helper method:
public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>( this IEnumerable<Expression<Func<T, bool>>> filters) { Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault(); if (firstFilter == null) { Expression<Func<T, bool>> alwaysTrue = x => true; return alwaysTrue; } var body = firstFilter.Body; var param = firstFilter.Parameters.ToArray(); foreach (var nextFilter in filters.Skip(1)) { var nextBody = Expression.Invoke(nextFilter, param); body = Expression.OrElse(body, nextBody); } Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param); return result; }
And now all together:
if (skuFilters.Any()) //this part goes into where it says "TODO" { Expression<Func<WidgetHistory, bool>> theSkuFilter = skuFilters.OrTheseFiltersTogether() query = query.Where(theSkuFilter); }