2015-04-01 51 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))