使用相交我得到一个本地序列不能在查询运算符的 LINQ 到 SQL 实现中使用,但包含运算符除外

本文关键字:运算符 LINQ SQL 实现 查询 包含 一个 不能 | 更新日期: 2023-09-27 18:37:16

我正在使用 Linq to SQL 查询来提供与数据库字段匹配的搜索词列表。 搜索词是内存中的字符串数组。具体来说,我在 Linq 查询中使用"相交",将搜索词与数据库字段"描述"进行比较。 在下面的代码中,描述字段是iss.description。 说明字段在 Linq 查询中分隔成一个数组,相交用于比较搜索词和说明词,以保留 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 Query 返回所有匹配结果(说明中搜索词的命中数),包括不匹配的记录并提供内存中列表<>然后使用另一个 Linq 查询筛选出不匹配的记录。

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 表达式来对它们进行排序,但我的试验没有成功。

任何帮助将不胜感激。

使用相交我得到一个本地序列不能在查询运算符的 LINQ 到 SQL 实现中使用,但包含运算符除外

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

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);
         }                    
      }