为什么这个LINQ-to-SQL查询会出现NotSupportedException?

Edw*_*uay 7 c# linq linq-to-sql

以下LINQ语句:

public override List<Item> SearchListWithSearchPhrase(string searchPhrase)
{
    List<string> searchTerms = StringHelpers.GetSearchTerms(searchPhrase);

    using (var db = Datasource.GetContext())
    {
        return (from t in db.Tasks
                where searchTerms.All(term => 
                    t.Title.ToUpper().Contains(term.ToUpper()) &&
                    t.Description.ToUpper().Contains(term.ToUpper())) 
                select t).Cast<Item>().ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

给我这个错误:

System.NotSupportedException:除Contains()运算符外,本地序列不能用于查询运算符的LINQ to SQL实现.

看看它似乎我唯一的选择是将我的所有项目首先放入一个通用列表,然后对其进行LINQ查询.

或者是否有一种巧妙的方法来重新编写上述LINQ-to-SQL语句以避免错误?

回答:

感谢Randy,您的想法帮助我构建了以下解决方案.它不优雅,但它解决了问题,因为这将是代码生成,我可以处理多达20个搜索术语,而无需任何额外的工作:

public override List<Item> SearchListWithSearchPhrase(string searchPhrase)
{
    List<string> searchTerms = StringHelpers.GetSearchTerms(searchPhrase);

    using (var db = Datasource.GetContext())
    {

        switch (searchTerms.Count())
        {
            case 1:
                return (db.Tasks
                     .Where(t =>
                         t.Title.Contains(searchTerms[0])
                         || t.Description.Contains(searchTerms[0])
                         )
                     .Select(t => t)).Cast<Item>().ToList();
            case 2:
                return (db.Tasks
                     .Where(t =>
                         (t.Title.Contains(searchTerms[0])
                         || t.Description.Contains(searchTerms[0]))
                         &&
                         (t.Title.Contains(searchTerms[1])
                         || t.Description.Contains(searchTerms[1]))
                         )
                     .Select(t => t)).Cast<Item>().ToList();
            case 3:
                return (db.Tasks
                     .Where(t =>
                         (t.Title.Contains(searchTerms[0])
                         || t.Description.Contains(searchTerms[0]))
                         &&
                         (t.Title.Contains(searchTerms[1])
                         || t.Description.Contains(searchTerms[1]))
                         &&
                         (t.Title.Contains(searchTerms[2])
                         || t.Description.Contains(searchTerms[2]))
                         )
                     .Select(t => t)).Cast<Item>().ToList();
            default:
                return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ran*_*der 1

艾德,我也遇到过类似的情况。代码如下。重要的代码行是我设置 memberList 变量的地方。看看这是否适合您的情况。抱歉,如果格式效果不佳。

兰迪

// Get all the members that have an ActiveDirectorySecurityId matching one in the list.
IEnumerable<Member> members = database.Members
   .Where(member => activeDirectoryIds.Contains(member.ActiveDirectorySecurityId))
   .Select(member => member);

// This is necessary to avoid getting a "Queries with local collections are not supported"
//error in the next query.    
memberList = members.ToList<Member>();

// Now get all the roles associated with the members retrieved in the first step.
IEnumerable<Role> roles = from i in database.MemberRoles
   where memberList.Contains(i.Member)
   select i.Role;
Run Code Online (Sandbox Code Playgroud)