【问题标题】:Using Intersect I'm getting a Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator使用 Intersect 我得到一个 Local 序列不能用于查询运算符的 LINQ to SQL 实现,但 Contains 运算符除外
【发布时间】:2012-06-15 16:59:36
【问题描述】:

我正在使用 Linq to SQL 查询来提供与数据库字段匹配的搜索词列表。搜索词是内存中的字符串数组。具体来说,我在 Linq 查询中使用“相交”,将搜索词与数据库字段“描述”进行比较。在下面的代码中,描述字段是 iss.description。 description 字段在 Linq 查询中被分隔成一个数组,并且 intersect 用于比较搜索词和描述词,以保持 Linq 查询中的所有比较和条件,这样数据库就不会被征税。在我的研究中,试图克服这个问题,我发现不支持使用内存或“本地”序列。我在研究过程中也尝试了一些建议,比如使用“AsEnumerable”或“AsQueryable”没有成功。

searchText = searchText.ToUpper();
var searchTerms = searchText.Split(' ');

var issuesList1 = (
    from iss in DatabaseConnection.CustomerIssues

    let desc = iss.Description.ToUpper().Split(' ')
    let count = desc.Intersect(searchTerms).Count()
    where desc.Intersect(searchTerms).Count() > 0

    join stoi in DatabaseConnection.SolutionToIssues on iss.IssueID equals stoi.IssueID into stoiToiss
    from stTois in stoiToiss.DefaultIfEmpty()
    join solJoin in DatabaseConnection.Solutions on stTois.SolutionID equals solJoin.SolutionID into solutionJoin
    from solution in solutionJoin.DefaultIfEmpty()
    select new IssuesAndSolutions
    {
        IssueID = iss.IssueID,
        IssueDesc = iss.Description,
        SearchHits = count,
        SolutionDesc = (solution.Description == null)? "No Solutions":solution.Description,
        SolutionID = (solution.SolutionID == null) ? 0 : solution.SolutionID,
        SolutionToIssueID = (stTois.SolutionToIssueID == null) ? 0 : stTois.SolutionToIssueID,
        Successful = (stTois.Successful == null)? false : stTois.Successful
    }).ToList();
    ...

我成功的唯一方法是创建两个查询并调用如下所示的方法,但这需要 Linq 查询返回所有匹配结果(描述中包含搜索词的命中数),包括不匹配的记录并提供一个内存列表,然后使用另一个Linq Query过滤掉不匹配的记录。

public static int CountHits(string[] searchTerms, string Description)
    {
        int hits = 0;
        foreach (string item in searchTerms)
        {
            if (Description.ToUpper().Contains(item.Trim().ToUpper())) hits++;
        }            
        return hits;
    }
    public static List<IssuesAndSolutions> SearchIssuesAndSolutions(string searchText)
    {
        using (BYCNCDatabaseDataContext DatabaseConnection = new BYCNCDatabaseDataContext())
        {
            searchText = searchText.ToUpper();
            var searchTerms = searchText.Split(' ');

            var issuesList1 = (
                from iss in DatabaseConnection.CustomerIssues
                join stoi in DatabaseConnection.SolutionToIssues on iss.IssueID equals stoi.IssueID into stoiToiss
                from stTois in stoiToiss.DefaultIfEmpty()
                join solJoin in DatabaseConnection.Solutions on stTois.SolutionID equals solJoin.SolutionID into solutionJoin
                from solution in solutionJoin.DefaultIfEmpty()
                select new IssuesAndSolutions
                {
                    IssueID = iss.IssueID,
                    IssueDesc = iss.Description,
                    SearchHits = CountHits(searchTerms, iss.Description),
                    SolutionDesc = (solution.Description == null)? "No Solutions":solution.Description,
                    SolutionID = (solution.SolutionID == null) ? 0 : solution.SolutionID,
                    SolutionToIssueID = (stTois.SolutionToIssueID == null) ? 0 : stTois.SolutionToIssueID,
                    Successful = (stTois.Successful == null)? false : stTois.Successful
                }).ToList();

            var issuesList = (
                from iss in issuesList1
                where iss.SearchHits > 0
                select iss).ToList();
                ...

我会对两个 Linq 查询感到满意,但第一个 Linq 查询只返回匹配的记录,然后可能使用第二个,也许是 lambda 表达式对它们进行排序,但我的试验没有成功。

任何帮助将不胜感激。

【问题讨论】:

  • 看看这个Similar Question,我最后回答了我自己的问题。
  • 感谢您的帮助。我根据您的链接查看了类似的问题,但我没有在该页面上看到本地序列问题的解决方案。您如何解决本地序列问题(Linq to SQL 不支持的序列)?
  • 在我对该链接的回答中,我创建了 Empty Iqeuryable 并且只是对我的字符串列表和联合查询中的单词进行了 foreach 以搜索每个单词。这解决了本地问题,在它搜索的位置创建查询每个字符串 seapratly 而不是整个 List 这是本地序列。
  • 谢谢,我会尝试这个解决方案。我可能需要一段时间才能弄清楚 lambda,因为那是我的薄弱环节。我会告诉你的。
  • 我尝试了您提供的解决方案,但是由于我的 Linq 查询设置为向空记录提供信息,我陷入了空引用的漩涡。然而,我确实找到了解决方案(如下)。

标签: c# linq-to-sql sequence local intersect


【解决方案1】:

好的,所以在更多地搜索更多技术并尝试了 user1010609 的技术后,我在几乎完全重写后设法让它工作。以下代码首先提供了一个包含我正在搜索的所有信息的平面记录查询,然后将过滤后的信息与搜索词进行比较形成一个新列表(计算每个搜索词的点击量以按相关性排序)。我小心地不返回平面文件的列表,这样在最终的数据库检索中会有一些效率(在过滤的 List 的形成期间)。我很肯定这甚至不是一种有效的方法,但它确实有效。我渴望看到更多独特的技术来解决这类问题。谢谢!

searchText = searchText.ToUpper();
List<string> searchTerms = searchText.Split(' ').ToList();

var allIssues =
    from iss in DatabaseConnection.CustomerIssues
    join stoi in DatabaseConnection.SolutionToIssues on iss.IssueID equals stoi.IssueID into stoiToiss
    from stTois in stoiToiss.DefaultIfEmpty()
    join solJoin in DatabaseConnection.Solutions on stTois.SolutionID equals solJoin.SolutionID into solutionJoin
    from solution in solutionJoin.DefaultIfEmpty()
    select new IssuesAndSolutions
    {
        IssueID = iss.IssueID,
        IssueDesc = iss.Description,
        SolutionDesc = (solution.Description == null) ? "No Solutions" : solution.Description,
        SolutionID = (solution.SolutionID == null) ? 0 : solution.SolutionID,
        SolutionToIssueID = (stTois.SolutionToIssueID == null) ? 0 : stTois.SolutionToIssueID,
        Successful = (stTois.Successful == null) ? false : stTois.Successful
    };                

    List<IssuesAndSolutions> filteredIssues = new List<IssuesAndSolutions>();

    foreach (var issue in allIssues)
    {
        int hits = 0;
        foreach (var term in searchTerms)
        {
            if (issue.IssueDesc.ToUpper().Contains(term.Trim())) hits++;                        
        }
        if (hits > 0)
        {
             IssuesAndSolutions matchedIssue = new IssuesAndSolutions();
             matchedIssue.IssueID = issue.IssueID;
             matchedIssue.IssueDesc = issue.IssueDesc;
             matchedIssue.SearchHits = hits;
             matchedIssue.CustomerID = issue.CustomerID;
             matchedIssue.AssemblyID = issue.AssemblyID;
             matchedIssue.DateOfIssue = issue.DateOfIssue;
             matchedIssue.DateOfResolution = issue.DateOfResolution;
             matchedIssue.CostOFIssue = issue.CostOFIssue;
             matchedIssue.ProductID = issue.ProductID;
             filteredIssues.Add(matchedIssue);
         }                    
      }

【讨论】:

    猜你喜欢
    • 2012-12-06
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多