1

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

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 查询返回所有匹配结果(描述中搜索词的命中数),包括非匹配的记录并提供内存中的 List<> ,然后使用另一个 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 表达式对它们进行排序,但我的试验没有成功。

非常感激任何的帮助。

4

1 回答 1

0

好的,所以在搜索更多技术并尝试了 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-06-16T06:13:33.577 回答