У меня следующий запрос
var query = (from titles in db.Titles
join ratings in db.Ratings on titles.Rating equals ratings.Rating1
join synopsis in db.Synopsis on titles.Certificate equals synopsis.Certificate into items
from item in items.DefaultIfEmpty()
where titles.Rating_Release_Date >= DateTime.Parse(fromDate) &&
titles.Certificate < 1000000 &&
platformElements.Any(r => titles.Platforms.Contains(r)) && //here i get error Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
ratingElements.Any(r => titles.Rating.Contains(r))
orderby titles.Rating_Release_Date descending, titles.Submission_Title
select new {...}
Но я получаю ошибку, когда пытаюсь проверить, содержит ли поле (titles.Platforms) любой элемент из коллекции.
Локальная последовательность не может использоваться в реализациях LINQ to SQL операторов запросов, кроме оператора Содержит.
И теперь я не знаю, как правильно сделать where-clause. Первая идея - в цикле проверить, содержит ли Platforms элемент из списка, но также не знают, как его реализовать.
Я нашел эту статью. Как использовать LINQ Contains (string []) вместо Contains (string), но я не думаю, что пользовательское расширение будет работать в моем случае. Другие ответы platformElements.Contains(titles.Platforms)
: platformElements.Contains(titles.Platforms)
который не то, что мне нужно.
Тип titles.Platforms
- string
. Тип platformElements
- string[]
;
Я не скомпилировал его, но он должен быть компилируемым.
Новый класс PredicateBuilder:
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> False<T>() {
return f => false;
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) {
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
}
Новая функция:
public IQueryable<Title> FilterByPlatforms(this IQueryable<Title> titles, string[] platformElements) {
var predicate = PredicateBuilder.False<Title>();
foreach (string platformElement in platformElements) {
string temp = platformElement;
predicate = predicate.Or(t => t.Platforms.Contains(temp));
}
return titles.Where(predicate);
}
Измененный запрос:
var query = (from titles in db.Titles.FilterByPlatforms(platformElements)
join ratings in db.Ratings on titles.Rating equals ratings.Rating1
join synopsis in db.Synopsis on titles.Certificate equals synopsis.Certificate into items
from item in items.DefaultIfEmpty()
where titles.Rating_Release_Date >= DateTime.Parse(fromDate) &&
titles.Certificate < 1000000 &&
// platformElements.Any(r => titles.Platforms.Contains(r)) && //here i get error Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
ratingElements.Any(r => titles.Rating.Contains(r))
orderby titles.Rating_Release_Date descending, titles.Submission_Title
select new {...}
Возможно, для ratingElements вы должны сделать то же самое.
Источник: http://www.albahari.com/nutshell/predicatebuilder.aspx