2017-02-02 52 views
-1

我設法開發了我的第一個具有CRUD功能的MVC 5 Web應用程序。LINQ包含奇怪的行爲

我的數據有很少的方式來搜索記錄,但其中一個似乎沒有做我所期望的。這裏是我的控制器搜索查詢代碼:

query = query.Where(c => 
     c.PostCode.Contains(searchString) 
     || c.Place1.Select(e => e.PostCode).Contains(searchString) 

這裏是我的模型:

public Place() 
    { 
     Place1 = new HashSet<Place>(); 
    } 

    [Display(Name = "Postcode")] 
    public string PostCode { get; set; } 

    public virtual ICollection<Place> Place1 { get; set; } 

我的數據庫的關係是自引用表 - > 1比0,對於域,因此相同的名稱。

任何人都可以解釋爲什麼搜索功能會在爲代碼的兩部分搜索完整值「NR32 4TW」時帶來預期結果,但只有搜索的第一個查詢部分(Before OR運算符)會找到如果我使用「NR32 4T」進行部分搜索,是否也有同樣的記錄?

我檢查了數據庫中的其他字段的查詢,他們有同樣的問題。

TDLR; LINQ「.Contains()」在模型中的集合上使用它時不搜索字符串的各個部分。有誰能解釋這種行爲嗎?

+1

LINQ是一個接口。你在使用實體框架嗎?這是實現LINQ接口的原因。 –

+0

您正將'Enumerable.Contains'與'string.Contains'混合使用。第二個標準應該是'c.Practice1.Any(e => e.PostCode。包含(搜索字符串))'。 –

回答

5

完全沒有考慮到,你有一個差異帳戶.... Practice1和PLACE1 您正在使用2種不同功能的名稱

「包含」

c.PostCode.Contains(searchString) 

這是String.Contains(string) ..它尋找你所稱的字符串中的參數...

c.Practice1.Select(e => e.PostCode).Contains(searchString) 

這是IEnumerable<string>.Contains(string) ......它會在字符串枚舉的字符串...

你想要做什麼是最有可能的:

c.PostCode.Contains(searchString) || c.Practice1.Any(e => e.PostCode.Contains(searchString)) 
+0

我已經調整了代碼在第一行反映你的評論。很好的答案,謝謝! – Newseek

1

Enumerable.Contains()正在搜索一個序列(列表),看看是否有確切的值。它不是搜索文本。

+0

PostCode是一個字符串。如果它的EF然後Contains調用應該被翻譯成LIKE –

+1

@SergeyBerezovskiy如果你在一個'string'上調用'Contains',那麼是的,你問這個字符串是否包含一個子字符串。如果你在一組值上調用'Contains' *,你問的是該值是否在該集合中,而不是該值中的值的子字符串。 – Servy

+2

@SergeyBerezovskiy而這就是爲什麼他說它適用於OR語句的第一部分,但不是第二部分。第二部分是序列:'c.Place1.Select(e => e.PostCode).Contains(searchString)' –

1

您要搜索的每個PostCode的字符串值的部分值,但是您的代碼將在郵政編碼列表中搜索完整的搜索值。區別在於你把你的右括號放在哪裏。

c.Practice1.Select(e => e.PostCode).Contains(searchString) 

VS

c.Practice1.Select(e => e.PostCode.Contains(searchString)) 

利用後者經過各PostCode的字符串和匹配字符串包含searchString,前者選擇所有PostCode當時的中後期代碼的列表中查找匹配到確切的searchString