2015-04-01 47 views
0

我已經創建了一個匹配的方法,基本上在Person對象,調用一個地址服務,然後嘗試做一個匹配首先嚐試像like然後如果這不起作用,它將房屋名稱/號碼與saon信息(平面1a等)連接起來,看看是否有效。通過檢查,如果不爲空仍然分配爲空

如果它找到了一個匹配,我需要將匹配的地址存儲在我的變量matchingAddress中,然後進一步處理該方法的其餘部分,我爲了清晰起見將其排除在外。

問題

我想我有我的lamda語句的問題,在第二IF與我同if語句返回true,我拖放到指定代碼但它是調試的人即使IF聲明旨在檢查它不是null,也會設置爲空。

任何人都可以解釋這裏發生了什麼?

private void AttemptMatch(Person person, string username) 
     { 
      var postcode = person.Postcode; 

      List<JsonAddressModel> Addresses = _service.GetAddress(postcode); //returns a list of addresses for that persons postcode 
      JsonAddressModel matchingAddress = new JsonAddressModel(); 

      //1.) Access the Service and see if theres a straight forward match 
      if (Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null) 
      { 
       matchingAddress = Addresses.First(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo);     
      } 

      //2.) try and combine the paon and saon and see if that matches address line one    

      if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null) 
      { 
       matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault(); 
      } 

      if (matchingAddress != null) 
      { 
       //rest of method to complete matching process for matched person   
      } 

      else 
       return; 
     } 

回答

2

停止重複的工作,只是去掉了一些這個條件邏輯:

//1.) Access the Service and see if theres a straight forward match 
//if (Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null) 
//{ 
matchingAddress = Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && 
       x.thorofare.Trim() == person.AddressLineTwo) ??     
//} 

//2.) try and combine the paon and saon and see if that matches address line one    

//if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null) 
//{ 
    /*matchingAddress = */ 
Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == 
       person.AddressLineOne && 
       x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault();    
//} 

你目前的問題是由於在第二個if中,您沒有調用任何選擇方法(如FirstOrDefaultToList等),因此您要檢查的是查詢是否爲空ra比任何結果。


此刻,你運行一個查詢僅僅是爲了確定它是否返回任何結果,然後運行該查詢再次實際獲得這些結果。然後,你有可能(如果你沒有得到第二個if有點不對)再次做同樣的技巧,使用它來覆蓋以前的結果引導,我相信這是你想要的實際結果。因此,我們只運行一個查詢,如果它返回null,我們使用??來移動並嘗試第二個查詢。

+0

我應該說List.Where或List.FirstOrDefault? – JsonStatham 2015-04-01 13:42:40

+1

如果'FirstOrDefault'調用沒有自己的lambda,那麼'Where''後面跟'FirstOrDefault'可以總是(我認爲)被合併爲一個'FirstOrDefault'調用 - 很容易(如這裏)在哪裏並且將其lambda放在'FirstOrDefault'中),或者如果兩個lambda必須被組合,則需要更多努力。有些工具(比如Resharper)甚至會在你寫'Where().FirstOrDefault()'時提醒你。 – 2015-04-01 13:55:23

+0

Resharper會爲您解答;)。它表明,每次鏈接一個Where和First [OrDefault]或Single [OrDefault] – Juan 2015-04-02 16:25:14

1

你進入if的原因是,你是不是叫FirstOrDefault()的條件內。與null進行比較的是Where方法的返回值,該方法永遠不會是null

您可以通過存儲的FirstOrDefault結果在一個臨時變量,然後分配給它,只有當它不是null優化代碼:

var tmp1 = Addresses.FirstOrDefault(x => x.paon.Trim() == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo); 
if (tmp1 != null) { 
    matchingAddress = tmp1;     
} 
var tmp2 = Addresses.FirstOrDefault(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo); 
if (tmp2 != null) { 
    matchingAddress = tmp2; 
} 
1

嘗試改變這一點:

Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null 

對於

Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo) != null 

理想情況下,你不需要th如果。你的SingleOrDefault應該是訣竅。

基本上,如果從來沒有返回NULL,它只是返回你已經做了空IEnumerable的

0

此linq正在返回集合,它始終不爲null。它可以是空的,但不能爲空。

試試這個:

if (Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo)) 
{ 
matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault(); 
} 

它會檢查是否有任何匹配項。

0

你可以在你的第二個試試這個,如果:

 if (Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault() != null) 
     { 
      matchingAddress = Addresses.Where(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo).FirstOrDefault(); 
     } 

的 'Addresses.Where(過濾器)' 返回NULL是不可能的。當IEnumerable<T>中的所有元素都不滿足where過濾器時,將返回空值IEnumerable<T>

1

永不返回空值。你需要檢查返回的集合是否爲空。

我想最好的辦法是改變「其中」與「任何」

if (Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo))