I have an Expression that looks like this:
obj => obj.Child.Name
where Name is a string. What I want to do is get the value of Name. I can get it just fine by compiling the method and invoking it, however a NullReferenceException is thrown if Child is null. Is there a way to check if Child is null in this scenario?
With the current C# version 5.0 (or lower), you have to explicitly check for each property like:
if(obj != null && obj.Child != null)
{
//get Name property
}
With C# 6.0 you will be able to check it using Null conditional/propagation operator.
Console.WriteLine(obj?.Child?.Name);
obj => obj.Child == null ? null : obj.Child.Name
or using C# 6
obj => obj.Child?.Name
obj => obj.Child == null ? "" : obj.Child.Name;
You can filter them previously(with a Where), something like this:
var results = source.Where(obj => obj.Child != null).Select(obj => obj.Child.Name);
Like this, you will prevent those null reference errors.
Related
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...
}
I am working on a project where I use Linq for fetching data. Now I have a scenario where I have to check field value contains given string for that I use Contains() function.
Everything works fine, But when any of the field is null then it creates a problem.
personData = personData.Where(x => x.FirstName.ToLower().Contains(q.ToLower()) || x.LastName.ToLower().Contains(q.ToLower())).Select(x => x).ToList();
Here when FirstName or LastName field have a null value it throw an error.
So, how can I overcome from this problem ?
Use following approach: x.FirstName?.Contains(substring) ?? false
Since C# 6 you can use null-conditional operators, that simplifies some queries greatly. You can read more about this topic here
Please try this
personData = personData.Where(x => (x.FirstName != null && x.FirstName.ToLower().Contains(q.ToLower())) || (x.LastName != null && x.LastName.ToLower().Contains(q.ToLower()))).Select(x => x).ToList();
You must check first if required values are null, Try using the null-coalescing operator...
personData = personData.Where(x => ((x.FirstName.ToLower() ?? "").Contains(q.ToLower())) || ((x.LastName.ToLower() ?? "").Contains(q.ToLower()))).Select(x => x).ToList();
What about using a simple string extension like the following:
public static string AsNotNull(this string value)
{
if (string.IsNullOrWhiteSpace(value))
return string.Empty;
return value;
}
And then use it like:
x.FirstName.AsNotNull()
I think you should prevent ability to add null FirstName or LastName at the beggining. This kind of row seems unuseful.
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
}
I'm having a problem with a LINQ to SQL query, the data being returned from the server could be null so I've set up an if statement within the query but the query is still throwing an exception.
This is a shortened down version of the query code
var a = from b in db.branches
where (b.Location != null) ?
(
(Query.Location == null) ?
true :
//The following line causes the exception to be thrown
object.Equals(Query.Location.ToLower() , b.Location.ToLower())
) :
(
(Query.Location == null) ?
true :
false
)
select b;
If the search term "Location" is null then I don't want to filter by location, but if it isn't null then I have to check if the value in the row is null or not as some of entries have a null location.
The code works fine until I add in the compare line. In order to get to the compare line, both Query.Location and b.Location cannot be null therefore the code shouldn't fail.
Any idea what the problem could be?
Thanks.
EDIT
If i remove the .toLower() from the object.equals call then the query runs correctly, it also manages to work no matter what case the query is in.
var a = from b in db.branches
where (b.Location != null) ?
(
(Query.Location == null) ?
true :
//The following line causes the exception to be thrown
object.Equals(Query.Location , b.Location)
) :
(
(Query.Location == null) ?
true :
false
)
select b;
I wouldn't like to say for sure what's going wrong here, but I think you could actually make your code significantly simpler by splitting it into two different queries:
public void Search(SearchTerms Query)
{
var queryWithLocation = db.branches.Where(b =>
Query.Location.Equals(b.Location, StringComparison.OrdinalIgnoreCase);
var query = Query.Location != null ? queryWithLocation : db.branches;
}
I've changed the way of doing the Equals - that's the way I prefer to perform case-insensitive searches; you'll have to see whether it works for LINQ to SQL.
Try this;
public void Search(SearchTerms Query)
{
var a = from b in db.branches
where (b.Location != null) ?
(
(Query.Location == null) ?
true
:
//The following line causes the exception to be thrown
Query.Location.ToLower() == b.Location.ToLower()
)
:
(
(Query.Location == null) ?
true
:
false
)
select b
}
I believe the object is probably causing the NullReference
from b in db.branches
let location = b.Location
where location != null ?
b.Location.Equals(b.Location, Query.Location ?? b.Location, StringComparison.OrdinalIgnoreCase) : // if Query.Location is null then select all
false // to select nothing in this case
select b;
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();