Null check in where? - c#

I have the following:
var tagId = "5288";
source.Where(p => p.GetPropertyValue<IEnumerable<string>>("picker").Contains(tagId));
This returns the error System.ArgumentNullException: Value cannot be null.
So some of the returned results, does not contain a picker value. How would I check for this, in the above statement?
It is a Umbraco Multinode treepicker that is the "picker" value.

If I understand correctly, the result of GetPropertyValue can be null if the picker value is not found. In that case, you can use a null conditional operator:
source.Where(p => p.GetPropertyValue<IEnumerable<string>>("picker")?.Contains(tagId) == true);
Note the ?. after GetPropertyValue. If that method returns null then it's not true, so those will not be included in the filtered objects.

Use this:
source.Where(p =>
{
var pickerVal = p.GetPropertyValue<IEnumerable<string>>("picker");
if (pickerVal == null)
return false;
return pickerVal.Contains(tagId);
});
or more condensed:
source.Where(p =>
{
var pickerVal = p.GetPropertyValue<IEnumerable<string>>("picker");
return (pickerVal != null) && pickerVal.Contains(tagId);
});

Related

How to resolve object reference error in lambda expression of linq in c#?

I am working on WPF application. In which I am trying to fetch records from list as per required condition. But when there is no any record found then it's giving me object reference not found error.
var recordList = _outputVariables.ToList().Where(X => X.symbolName == _symbolName).ToList();
if (recordList != null)
{
//more coding...
}
so as shown in code when _outputVariables have no any record match as per _symbolName then it's giving error of Object reference not set to an instance of an object.' and X was null.. So how can I handle this issue ? please help for it.
Use the null-conditional operator that was introduced in C#6 (and don't call ToList() more than once):
var recordList = _outputVariables?.Where(X => X?.symbolName == _symbolName).ToList();
if (recordList != null)
{
//more coding...
}
var recordList = _outputVariables.ToList().Where(X => X.symbolName == _symbolName).ToList();
You currently loop through _outputVariables, but if it's null this will give an error, because null does not have a .ToList(). So you should add a ? after your _outputVariables, so it will return null instead of an exception when it's null.
Same goes for X. If X is null and you try to get the property symbolName, you will get an error, because null doesn't have a property called symbolName. So you want to add a ? here too. So it will return null instead of an exception.
Leaving you with: var recordList = _outputVariables?.ToList().Where(X => X?.symbolName == _symbolName).ToList();
You can use like below as well
if (_outputVariables != null && _outputVariables.Count > 0)
{
var recordList = _outputVariables.Where(X => X != null && !string.IsNullOrEmpty(X.symbolName) && X.symbolName == _symbolName);
}
You can try this
if(_outputVariables!=null)
{
var recordList = _outputVariables.Where(X => X.symbolName ==_symbolName).ToList();
}
if (recordList != null)
{
//more coding...
}

How to deal with null linq query result?

I have a linq query in which i am getting the user list and after that we are getting the record by userid filter.
var user = UserDal.GetAllUsers().First(n => n.UsersID == 1);
But what should do if GetAllUsers() function returns null ? Should we check it by applying Any() ? Or something else ?
But what should do if GetAllUsers() function returns null ?
If UserDal.GetAllUsers returns null, then you can't use Any, you will have to check it against null. You can only use Any or FirstOrDefault if the method returns a collection (even empty).
If the method could return null then:
var temp = UserDal.GetAllUsers();
if(temp != null)
{
var user = temp.FirstOrDefault(n=> n.UserID == 1);
}
If your method could return an empty collection instead of null then you can do:
var user = UserDal.GetAllUsers().FirstOrDefault(n => n.UsersID == 1);
You should modify your method UserDal.GetAllUsers to not return a null. If there are no records then an empty collection should be returned.
Why not simply check if it is null?
var users = UserDal.GetAllUsers();
if (users == null || !users.Any())
{
// handle error
}
var user = users.First(x => x.Id == someId);
However, if you're in control of the code-base, I'd certainly say that you should make it so GetAllUsers never returns null.
You could use [DefaultIfEmpty] and use that instance as default value: to handle null value
You could use Monads, e.g. https://github.com/sergun/monads.net
Or you could implement your own extension methods.
This code is adapted from the original extension method and returns default(T) instead of throwing an exception.
// UserDal.GetAllUsers() returns null and user is null
var user = UserDal.GetAllUsers().MyFirstOrDefault(n => n.UsersID == 1);
public static class IEnumerableExtensions
{
public static T MyFirstOrDefault<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
if (source == null) return default(T);
if (predicate == null) return default(T);
foreach (T element in source)
{
if (predicate(element)) return element;
}
return default(T);
}
}
Or you could use null checks or ensure never to return null to safeguard against null reference exception when using the standard extension methods.

FirstOrDefault returns NullReferenceException if no match is found

Here is my code:
string displayName = Dictionary.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID)).Value.DisplayName;
The code works fine if x.Value.ID matches options.ID. However, I get a NullReferenceException if it doesn't.
FirstOrDefault returns the default value of a type if no item matches the predicate. For reference types that is null. Thats the reason for the exception.
So you just have to check for null first:
string displayName = null;
var keyValue = Dictionary
.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID));
if(keyValue != null)
{
displayName = keyValue.Value.DisplayName;
}
But what is the key of the dictionary if you are searching in the values? A Dictionary<tKey,TValue> is used to find a value by the key. Maybe you should refactor it.
Another option is to provide a default value with DefaultIfEmpty:
string displayName = Dictionary
.Where(kv => kv.Value.ID == long.Parse(options.ID))
.Select(kv => kv.Value.DisplayName) // not a problem even if no item matches
.DefaultIfEmpty("--Option unknown--") // or no argument -> null
.First(); // cannot cause an exception
You can use a combination of other LINQ methods to handle not matching condition:
var res = dictionary.Where(x => x.Value.ID == someID)
.Select(x => x.Value.DisplayName)
.DefaultIfEmpty("Unknown")
.First();
Simply use the question mark trick for null checks:
string displayName = Dictionary.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID))?.Value.DisplayName ?? "DEFINE A DEFAULT DISPLAY NAME HERE";
That is because FirstOrDefaultcan return null causing your following .Value to cause the exception. You need to change it to something like:
var myThing = things.FirstOrDefault(t => t.Id == idToFind);
if(myThing == null)
return; // we failed to find what we wanted
var displayName = myThing.DisplayName;
To add to the solutions, here is a LINQ statement that might help
Utilities.DIMENSION_MemTbl.Where(a => a.DIMENSION_ID == format.ContentBrief.DimensionID).Select(a=>a.DIMENSION1).DefaultIfEmpty("").FirstOrDefault();
The result will be an empty string if the result of the query is a null..
This answer is for those of us who need a visual write up (like me :)
In the code screenshot below, a NullReferenceException will be thrown, the root cause is the ReferenceIdentification_02 property.
When debugging, we see that the orderLine.REF array, I am querying does not include a matching object whose ReferenceIdentificationQualifier_01 value == "RU", so at that point FirstOrDefault() return value is NULL
to prevent the NullReferenceException, I do a FirstOrDefault() on the orderLine.REF array first. If the returned value is not null then I retrieve the value.
i assume you are working with nullable datatypes, you can do something like this:
var t = things.Where(x => x!=null && x.Value.ID == long.Parse(options.ID)).FirstOrDefault();
var res = t == null ? "" : t.Value;
you can use with 'Where' statement with FirstOrDefault().
like this.
var modelItem = _dbcontext.ModelName.Where(n => n.NewsTagId == newsTag.Id).FirstOrDefault();
It returns first item if does not match query.
It is better practice to check the NULL after query.
if(modelItem == null)
{
return "Not Found."
}
else
{
// continue process
}

NullReferenceException using where clause

I have a scenario that I am getting the result properly .But i have to search it in that result.Here is my code.
if(productSearch.Keyword !=null || productSearch.Code!=null)
{
var key = productSearch.Keyword;
var cod = productSearch.Code;
if (productSearch.Code != null)
{
var Selected_Result = result.Results.Where(s => s.Code.ToLower().Contains(cod.ToLower())).ToList();
result.Results = Selected_Result;
}
else
{
var Selected_Result = result.Results.Where(s => s.Keyword.ToLower().Contains(key.ToLower())).ToList();
result.Results = Selected_Result;
}
}
But it gives following exception :
Object reference not set to an instance of an object on result.Results.Where(s => s.Code.ToLower().Contains(cod.ToLower())).ToList();
I know s => s.Code.ToLower() is coming NULL, but i dont know why, result has records.
Thanks in advance.
If it's null in the query then chances are it's null in the DB. To be on the safe side you can use the null coalescing operator to make sure you have at least something to call ToLower on e.g.
result.Results.Where(s => (s.Code ?? "").ToLower().Contains(cod.ToLower()))
.ToList();

How to check for null before I use in linq?

I have an list of objects that contains another object in it.
List<MyClass> myClass = new List<MyClass>();
I want to do some linq like this
myClass.Where(x => x.MyOtherObject.Name = "Name").ToList();
Thing is sometimes "MyOtherObject" is null. How do I check for this?
Simple, just add an AND clause to check if it's not null:
myClass.Where(x => x.MyOtherObject != null && x.MyOtherObject.Name = "Name").ToList();
As of C# 6, you can also use a null conditional operator ?.:
myClass.Where(x => x.MyOtherObject?.Name == "Name").ToList();
This will essentially resolve the Name property to null if MyOtherObject is null, which will fail the comparison with "Name".
Try it online
You can just make your predicate check for null...
myClass.Where(x => (x.MyOtherObject == null) ? false : x.MyOtherObject.Name == "Name").ToList();
I would do something like this:
myClass.Where(x => x.MyOtherObject != null)
.Where(y => y.MyOtherObject.Name = "Name")
.ToList();

Categories