1

Linq to SQLクエリを使用して、データベースフィールドと一致する検索語のリストを提供しています。検索語はメモリ内の文字列配列です。具体的には、Linqクエリ内で「交差」を使用して、検索語をデータベースフィールド「説明」と比較しています。以下のコードでは、説明フィールドはiss.descriptionです。説明フィールドはLinqクエリ内で配列に分割され、交差は検索用語と説明用語を比較するために使用され、データベースに課税されないように、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();
    ...

私が成功した唯一の方法は、2つのクエリを作成し、以下に示すようにメソッドを呼び出すことですが、これには、Linqクエリが、非一致したレコードを指定し、メモリ内のリスト<>を提供してから、別の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();
                ...

2つのLinqクエリで問題はありませんが、最初のLinqクエリでは一致したレコードのみが返され、次に2番目のラムダ式を使用してそれらを並べ替えることができますが、試行は成功しませんでした。

どんな助けでも大歓迎です。

4

1 に答える 1

0

さて、さらに多くのテクニックを検索し、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);
         }                    
      }
于 2012-06-16T06:13:33.577 に答える