2016-01-26 36 views
0

我有一個LINQ語句,這樣說明哪些條件在LINQ被匹配,其中

dbContext.Items 
.Where(
p => 

    (p.Client.Contact != null && p.Client.Contact.Firstname.ToLower().Contains(searchText.ToLower())) 
    || 
    (p.Client.Contact != null && p.Client.Contact.Surname.ToLower().Contains(searchText.ToLower())) 
    || 
    (p.PolicyNumber != null && p.PolicyNumber.ToLower().Contains(searchText.ToLower())) 
    || 
    (
    p.PolicyLivesAssureds 
    .Where(
     pl => 
     pl.Contact != null && pl.Contact.Firstname.ToLower().Contains(searchText.ToLower()) 
     || pl.Contact.Surname.ToLower().Contains(searchText.ToLower()) 
     ).Count() > 0 
) 
) 
).OrderBy(p => p.IeUtem); 

這實際上是需要自動完成。我想要做的是能夠確切地知道我的5個條件中的哪些已匹配並顯示已匹配的特定項目。例如說,PolicyNumber已匹配,我想只發送該行的policynumber,對於其他人,如果名稱已匹配,我只想發送該行的名稱。

有沒有辦法做到這一點;

+0

單獨的查詢。通過這種方式,更容易計算單獨組件的結果並將結果存儲到專用對象中。雖然,由於您正在使用'OrderBy',您可能想要在某處再次合併數據。 – Stefan

+0

你使用C#6.0嗎?你這樣,一些表達式可以簡化爲:'p.Client.Contact!= null && p.Client.Contact.Firstname.ToLower()。Contains(searchText.ToLower())'''p.Client.Contact? .Firstname.ToLower()。包含(SEARCHTEXT。ToLower())' – Ian

回答

0

問題變成你想知道哪些查詢匹配。例如,你可以做這樣的事情

class AutoCompleteItem { 
    String Text {get; set;} 
    Item Item {get; set;} 
} 

var firstNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.FirstName, Item = p}) 

var lastNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.SurName, Item = p}) 

var result = firstName.Union(lastNames).Where(p => p.Name.Contains(searchText)).OrderBy(a => a.Item.IeUtem); 

現在AutcompleteItem是包含你想要的文本類(也可能是你需要的任何其他領域,如信息是該領域的匹配)

理念這裏是MVVM patttern。你有你的模型(項目)。現在你需要構造一個viewModel(AutoCompleteItems),它可以幫助你顯示你想要的東西。

+0

我可以做三個查詢,但我只限於數據庫調用的次數,我想做一個查詢 – user2327579

+0

Linq只會在您實際使用結果時執行您的查詢。所以當你做最後的ToList時,它應該執行整個查詢。 – Batavia

0

這是一個比較一個回味無窮的答案,因爲它有缺陷,在它的方式,但我認爲這不會解決你的問題:

double[] items = { 1, 2, 3, 4, 5 }; 
IEnumerable<Tuple<double, int>> results = items.Select(x => 
    { 
     int index = 0; 
     foreach (var condition in new Func<bool>[] 
      { 
       // TODO: Write conditions here. 
       () => x == 1, 
       () => x == 2 
      }) 
     { 
      if (condition() == true) 
       return index; 
      else 
       index++; 
     } 
     return -1; 
    }).Zip(items, (matchedCondtion, item) => Tuple.Create(item, matchedCondtion)) 
    .Where(x => x.Item2 != -1); 

我用一個簡單的雙陣列爲例的集合來過濾,但它只是一個例子,你可以使用任何東西。

第一個select將爲集合中的每個元素返回一個整數。如果有條件匹配,則返回條件的索引。如果不匹配,則返回-1。

它通過枚舉Func集合並返回第一個真實條件的索引(模擬||運算符的短路)來完成此操作。如果沒有條件匹配,則在評估所有條件後簡單地返回-1。

然後將這些結果用原始集合(使用Tuple)進行壓縮,將每個元素與匹配條件(或-1)的索引進行映射。

因此,例如將返回:

{ 1, 0 }, 
{ 2, 1 }, 
{ 3, -1 }, 
{ 4, -1 }, 
{ 5, -1 } 

這個結果那麼簡單的使用Where刪除與-1任何條目過濾,讓你與相匹配的條件元素的集合和條件的索引匹配(以Tuple的形式)。

所以自定義此爲您的解決方案,你可以刪除你想在任何條件數的例子條件和地點:由於您使用`或`我建議打破它在5

// TODO: Write conditions here.