Reputation: 1623
I have two entities where I Groupjoin
them into a list and I am trying to search for a match for a certain value in different properties.
The problem is that if one property has null value in the list, the search completly ignores the other properties and returns empty list.
I am posting the relevant code,
populating entities
,
List<PatientsRegistrySearchViewModel> SearchList = new List<PatientsRegistrySearchViewModel>();
List<PatientsRegistrySearchViewModel> DataResponse = new List<PatientsRegistrySearchViewModel>();
Groupjoin,
SearchList = (
from p in registryList
join c in registryAccountsList on p.PatientFileId equals c.PatientFileId into g
from c in g.DefaultIfEmpty()
select new PatientsRegistrySearchViewModel {
PatientFileId = p.PatientFileId,
Name = p.FirstName,
AliasName = p.AliasName,
PatientDob = p.PatientDob.ToString(),
PatientAge = 0,
PatientEmail = c?.Email,
SocialSecurityNo = p.SocialSecurityNo,
PatientMobileNo = c?.MobileNo
}).ToList();
and my search logic,
searchResults = (from i in SearchList where (
i.Name.ToLower().Contains (value.ToLower()) ||
i.PatientEmail.ToLower ().Contains (value.ToLower())
) select i).ToList();
this search logic will compare the value to Name
or PatientEmail
, if either prop is null in the list, the returned result is empty! Why (||) "or" operator is not skipping null?
list example,
{
patientFileId: 1111,
Name: "John",
aliasName: null,
patientDob: "1/25/85 12:00:00 AM",
patientAge: 0,
patientEmail: "[email protected]",
socialSecurityNo: "1212121SSN",
patientMobileNo: "3244990"
},
{
patientFileId: 2222,
Name: "Nicole",
aliasName: null,
patientDob: "1/1/01 12:00:00 AM",
patientAge: 0,
patientEmail: null,
socialSecurityNo: null,
patientMobileNo: null
},
{
patientFileId: 3333,
Name: "Nancy",
aliasName: null,
patientDob: "3/25/85 12:00:00 AM",
patientAge: 0,
patientEmail: "[email protected]",
socialSecurityNo: null,
patientMobileNo: "3244990"
}
Upvotes: 0
Views: 5945
Reputation: 1904
Ok, I made a small test which made my guess sure. Code snippet:
class Program
{
static void Main(string[] args)
{
var searchList = new List<TwoProps>()
{
new TwoProps() {Name = "sdfs1", PatientEmail="[email protected]" },
new TwoProps() {Name = "sdfs2", PatientEmail=null },
new TwoProps() {Name = "sdfs3", PatientEmail="[email protected]" }
};
var stringToSearch = "myMail".ToLower();
var query = (from listItem in searchList
where listItem.Name.ToLower().Contains(stringToSearch)
|| listItem.PatientEmail.ToLower().Contains(stringToSearch)
select listItem).ToList(); //NullReferenceException is thrown here @ second element
//listItem.PatientEmail.ToLower() => null.ToLower() => NRE
Console.WriteLine(query.Count());
}
private class TwoProps
{
public string Name { get; set; }
public string PatientEmail { get; set; }
}
}
You can fix this with ...|| (listItem.PatientEmail?.ToLower().Contains(stringToSearch) ?? false)
.
As expected, there is a NRE thrown. You are handling the exception somewhere and return a empty list or simply dont populate your list with teh result items(results are the same).
Upvotes: 2
Reputation: 392
For example:
AliasName = p.AliasName,
Replace With
AliasName = p.AliasName ?? ""
When p.AliasName is null, then AliasName is an empty string.
Upvotes: 1
Reputation: 31
The ||
operator plus the String.IsNullOrWhiteSpace
will INCLUDE values that are null
. And then you are trying to do a ToLower()
on a null
value.
Try this. It will first make sure the valie of email is not null then do the contains.
searchResults = (from i in SearchList where (
i.Name.ToLower ().Contains (value.ToLower ()) ||
(!string.IsNullOrWhiteSpace (i.PatientEmail) &&
i.PatientEmail.ToLower ().Contains (value.ToLower ()))
) select i).ToList ();
Upvotes: 1