我创建了一个匹配方法,它基本上接受一个Person
对象,调用一个地址服务,然后尝试首先尝试匹配,然后尝试匹配,然后如果它不起作用它连接房屋名称/编号与saon
信息(平面1a等),看看是否有效。
如果确实找到匹配项,我需要在我的变量matchingAddress
中存储匹配的地址,然后进一步处理该方法的其余部分,为清楚起见,我已将其排除在外。
问题
我认为我的lamda
语句存在问题,在第二个IF
上我正在调试的人使用if语句返回true并且我正在进入分配代码但是它是即使IF
语句要检查它不是null
,也被设置为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;
}
答案 0 :(得分:2)
停止重复你已经完成的工作 1 ,然后删除一些条件逻辑:
//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
中,您没有调用任何选择方法(例如FirstOrDefault
或ToList
等),所以您要检查的是查询是否为null而不是任何结果。
1 目前,您仅运行查询以确定它是否返回任何结果,然后再次运行查询 以实际获取这些结果。然后,你可能(如果你没有得到第二个if
稍微错误)第二次做同样的技巧,和使用它来覆盖以前的结果来启动,这是我相信你想要的实际结果。所以,相反,我们只运行一个查询,如果它返回null,我们使用??
移动并尝试第二个查询。
答案 1 :(得分: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;
}
答案 2 :(得分: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
理想情况下,如果你不满意的话。你的SingleOrDefault应该可以做到这一点。
基本上,Where永远不会返回null,它只返回一个空的IEnumerable
答案 3 :(得分:1)
永远不会返回null值。您需要检查返回的集合是否为空。
我认为最好的选择是将“where”改为“any”
if (Addresses.Any(x => String.Format("{0} {1}", x.paon.Trim(), x.saon.Trim()) == person.AddressLineOne && x.thorofare.Trim() == person.AddressLineTwo))
答案 4 :(得分: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();
}
它将检查是否有任何匹配的项目。
答案 5 :(得分: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(filter)'返回null是不可能的。当IEnumerable<T>
中的所有元素都不满足where过滤器时,它将返回空IEnumerable<T>