簡體   English   中英

LINQ:查詢的Foreach循環導致意外結果

[英]LINQ: Foreach loop on a query causing unexpected results

因此,我有此查詢,如果查詢中有匹配的單詞(名字,姓氏或電話號碼),則該查詢應返回一條記錄:

var searchWords = searchQuery
                .Split(' ')
                .Select(x => x.Trim()
                .ToLower())
                .Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();

foreach (var searchWord in searchWords)
        {
            var word = searchWord;
            someParentObjects= someParentObjects
            .Where(x => x.User.FirstName.ToLower().Contains(word) ||
            x.User.LastName.ToLower().Contains(word) ||
            x.User.CellPhone.Contains(word) 
            );
        }

以某種方式包含匹配不起作用,結果我得到零結果? 這是為什么?

注意:第一部分工作正常,我可以從searchQuery中獲取修剪后的單詞。

測試數據 :基本上我要做的就是根據查詢過濾結果。 如果查詢中有任何單詞與名字,姓氏或手機匹配,我將返回這些記錄。 因此,如果我在數據庫中有一個名字是“ James”而姓氏是“ Brian”的記錄,則如果我將查詢傳遞為“ James Something”,它應該返回一條記錄。 但是它沒有回來。 我得到零記錄。

您的代碼實際上過濾了至少一個字段中出現的所有“ searchWords”。 對於多個單詞,此類過濾很可能不會返回任何結果。

搜索條件“ Bob John”和患者“ John Doe”的foreach簡化版本:

var filtered = new[]{"John"}
 .Where(firstName => firstName.Contains("Bob"))
 .Where(firstName => firstName.Contains("John"));

盡管不清楚要尋找什么,但是可以選擇停止第一個非空結果:

    foreach (var searchWord in searchWords)
    {
        var word = searchWord;
        var filteredPatientSteps = patientSteps
        .Where(x => x.User.FirstName.ToLower().Contains(word) ||
        x.User.LastName.ToLower().Contains(word) ||
        x.User.CellPhone.Contains(word) 
        );
        if (filteredPatientSteps.Any())
        {
             // jump out on first match 
            patientSteps = filteredPatientSteps;
            break;
         }
    }

您在searchWords數組中得到“詹姆斯”嗎? 您的代碼似乎很好。 如果searchQuery包含“ James John Doe”之類的字符串,則searchWords的第一個元素將為“ James”,其余元素似乎都很好。 我已經厭倦了:

var searchQuery = "John Doe Brazil";

            var searchWords = searchQuery
                .Split(' ')
                .Select(x => x.Trim()
                    .ToLower())
                .Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();
            User obj=new User()
            {
                FirstName = "Ali",
                LastName = "John"
            };
            var someParentObjects =new[]{ new Parent(){Users =obj}};


            foreach (var searchWord in searchWords)
            {
                var word = searchWord;
              var ParentObjects = someParentObjects
                .Where(x => x.Users.FirstName.ToLower().Contains(word) ||
                x.Users
                .LastName.ToLower().Contains(word) 

                );
            }

我將用戶和父母帶到的位置:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Parent
{
    public User Users { get; set; }
    public Parent() { }

}

在這種情況下,ParentObjects返回對象Ali John。

編輯:要使用ParentObjects外循環,請執行以下操作:

List<Parent> ParentObjects=new List<Parent>();

            foreach (var searchWord in searchWords)
            {
                var word = searchWord;
               var ParentObject = someParentObjects.FirstOrDefault(x => x.Users.FirstName.ToLower().Contains(word) ||
                                                                        x.Users
                                                                            .LastName.ToLower().Contains(word));
                if(ParentObject!=null)
                ParentObjects.Add(ParentObject);
            }

然后可以在循環外部使用ParentObjects。

用foreach循環包裝linq語句通常表明出現了問題。 Linq已經為您完成了“循環”部分。

var searchWords = searchQuery
                .Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)
                .Select(x => x.Trim().ToUpper())
                .ToArray();

在這里,我們將搜索邏輯反向使用Any()來包含,Linq為我們處理了枚舉。

var result = (from step in patientSteps
              where searchWords.Any(x => 
              step.User.FirstName.ToUpper().Contains(x) ||
              step.User.LastName.ToUpper().Contains(x) ||
              step.User.CellPhone.Contains(x) )
              select step);

您提供的復制創建功能還不夠,但是如果我填寫其余內容,那么您現有的代碼似乎可以正常工作。

void Main() {
    string searchQuery = "foo bar";
    IEnumerable<PatientStep> patientSteps = new PatientStep[] {
        new PatientStep("foo", "bar", "12345"),
        new PatientStep("foo", "williams", "12345"),
        new PatientStep("nancy", "bar", "12345"),
        new PatientStep("nothing", "relevant", "12345"),
    };

    var searchWords = searchQuery
                    .Split(' ')
                    .Select(x => x.Trim()
                        .ToLower())
                    .Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();

    foreach (var searchWord in searchWords) {
        var word = searchWord;
        patientSteps = patientSteps.Where(
            x => x.User.FirstName.ToLower().Contains(word)
                || x.User.LastName.ToLower().Contains(word)
                || x.User.CellPhone.Contains(word)
        );
    }

    foreach (var patientStep in patientSteps) {
        Console.WriteLine(patientStep.ToString());
    }
}

class PatientStep {
    public User User { get; private set; }

    public PatientStep(string first, string last, string cell) {
        this.User = new User { FirstName = first, LastName = last, CellPhone = cell };
    }

    public override string ToString() {
        return string.Format("{0} {1}, {2}", this.User.FirstName, this.User.LastName, this.User.CellPhone);
    }
}

class User {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string CellPhone { get; set; }
}

產生輸出:

foo bar, 12345

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM