检查字段是否包含LinqToSql中集合中的任何项目

时间:2015-03-25 15:32:10

标签: c# sql linq linq-to-sql

我有下一个查询

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)是否包含来自集合的任何项目时,我收到错误。

  

除了Contains运算符之外,本地序列不能用于查询运算符的LINQ to SQL实现。

现在我不知道如何正确地制作where子句。 第一个想法 - 循环检查平台是否包含列表中的项目,但也不知道如何实现它。

我发现了这篇文章How do I use LINQ Contains(string[]) instead of Contains(string),但我不认为自定义扩展程序适用于我的情况。其他答案是这样的:platformElements.Contains(titles.Platforms)这不是我需要的。


titles.Platforms的类型为stringplatformElements的类型为string[];

1 个答案:

答案 0 :(得分: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