Проверьте, содержит ли поле какой-либо элемент из коллекции в LinqToSql

1

У меня следующий запрос

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[];

  • 0
    stackoverflow.com/questions/20567223/...
  • 0
    @ user3444160, в моем случае это не очень хорошее решение, так как оператор where делает огромную работу по фильтрации, так как у меня много данных
Теги:
linq
linq-to-sql

1 ответ

1

Я не скомпилировал его, но он должен быть компилируемым.

Новый класс 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню