I keep getting null exceptions when iterating over my foreach loop and I think it is because they
way I am trying to check, iterate and skip over the nulll values is incorrects. Basically when it doesnt fine "New" it throws an exception.
public async Task<IActionResult> NewRequisitionsEntryList()
{
//var requisitions = _repositoryWrapper.Requisition.GetAllNewRequisitions();
//UserInformation UserInformation = await _userManager.GetUserAsync(User);
var newReqList = _context.Requisition.OrderByDescending(r => r.Status.Equals("New")).ToList();
foreach (var reqList in newReqList ?? Enumerable.Empty<Requisition>())
{
UserInformation identityUser = await _userManager.GetUserAsync(User);
var departmentId = _context.Department.Where(x => x.DepartmentName == identityUser.Department).FirstOrDefault();
var userDepartmentId = departmentId.DepartmentId;
if (departmentId.DepartmentId == reqList.DepartmentId)
{
if (_context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault().ProcessStepName == "New")
{
CurrentStepName = _context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault().ProcessStepName;
requistionsNew.Add(new NewRequistionModel()
{
RequistionNo = reqList.RequisitionNo,
RequisitionTitle = reqList.RequisitionTitle,
DateCreated = reqList.DateCreated,
ProcessStepName = CurrentStepName,
RequestedBy = reqList.QueriesEmail,
});
}
}
}
await Task.Run(() =>
{
Console.WriteLine("workspace");
});
ViewData["requistionsNew"] = requistionsNew;
return View(newReqList);
}
Its breaking on the second if clause on the line that has the where statement
So you mean the second if clause makes error. We can analysis that firstly you use the _context before the if clause without any error, so it will not be null for the context. Then we can see you use FirstOrDefault which can get the model data, here can receive null value. Null value is acceptbale but if you want to get the property of the null object, it will throw exception.
You can simply use ? to avoid null exception:
_context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault()?.ProcessStepName;
Or change the if clause:
var model = _context.ProcessStepLog.Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault();
if (model !=null && model .ProcessStepName == "New")
Suggestions:
Actually debugging code is the most efficient way to find out the error and know how to modify. You need set the breakpoint to your action and quick watch the line which makes error, step by step to find where is the real error. For example, right-click and choose quick watch, then in the search bar type the _context.ProcessStepLog to check the value or Results View. If it contains value, then type Where(d => d.RequistionId == reqList.RequisitionId).FirstOrDefault() to check it. Step by Step.....
Refer to:
Use breakpoints in the Visual Studio debugger
Watch variables with Watch windows and QuickWatch
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...
}
In the below code, if i uncomment the line starting with queItem.RequestedMap == null I get
Non-static method requires a target.
If I then instead rewrite it as it is now, with a .ToList() and then doing the same where query after that it works. This tells me that .net is not able to translate the null check of queItem.RequestedMap == null into something sql specific.
queItem is an object paramater passed to the method containing this code.
Is there a way I can write this without retrieving the data back to .net and then doing another where? The existing answers I found just said to remove such expressions from the lambda query, which I dont want to do.
var gameToJoin = db.Games
//.Where(x =>
// (queItem.RequestedMap == null || x.Map.Id == queItem.RequestedMap.Id) // no map preference or same map
//)
.ToList()
.Where(x =>
queItem.RequestedMap == null
|| x.Map.Id == queItem.RequestedMap.Id) // no map preference or same map)
.FirstOrDefault();
Edit: Also, in the real query expression there are multiple other expressions in the first .Where that is commented here, they always need to be checked.
var gameToJoin = db.Games.AsQueryable();
// add the where's that always need to be checked.
if (queItem.RequestMap != null)
{
gameToJoin = gameToJoin.Where(x => x.Map.Id = queItem.RequestMap.Id);
}
var result = gameToJoin.ToList();
Or if you'd rather use FirstOrDefault()
var gameToJoin = db.Games.AsQueryable();
// add the where's that always need to be checked.
if (queItem.RequestMap != null)
{
var result = new List<Game>();
var game = gameToJoin.FirstOrDefault(x => x.Map.Id = queItem.RequestMap.Id);
if (game != null)
{
result.Add(game);
}
return result;
}
return gameToJoin.ToList();
Wouldn't this produce what you want? I don't see a reason that queItem.RequestedMap check should be a part the LINQ, because it is not a part the database.
Game gameToJoin = null;
if(queItem.RequestedMap == null)
{
gameToJoin = db.Games
.Where(x => x.Map.Id == queItem.RequestedMap.Id)
.FirstOrDefault;
}
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 am trying to fix these linq statements so that they wont error if the model is null.
For example:
model.FilterSet.Dispositions may be null. While model.FilterSet.GenderFilters may not.
My current linq statement gives error if there is a null so I tried to add .Where(item => item != null) in the DispositionFilters linq, but it gives me an error saying that this will always be true.
Here is my code:
var filters = new RespondentCSVFilters
{
CSVFilters = new CSVFilters
{
DispositionFilters = model.FilterSet.Dispositions.Where(item=>item != null).ToList().ConvertAll(item => (int)((RespondentStatus)Enum.Parse(typeof(RespondentStatus), item.ToString()))),
EthnicitiesFilters = model.FilterSet.Ethnicities.ConvertAll(item => (int)((Ethnicity)Enum.Parse(typeof(Ethnicity), item.ToString()))),
GenderFilters = model.FilterSet.Genders.ConvertAll(item => (int)((Gender)Enum.Parse(typeof(Gender), item.ToString()))),
SourcesFilters = model.FilterSet.Sources.ConvertAll(item => (int)((RespondentSource)Enum.Parse(typeof(RespondentSource), item.ToString()))),
}
};
I am not sure how to make the changes in order to handle nulls.
I tried to add .Where(item => item != null)
But this will only check each item for null, not the source ("Dispositions"). To check for null fluently (without adding a bunch of "if" statements), an EmptyIfNull extension can be helpful:
public static class Extensions
{
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> self)
{
return self == null ? Enumerable.Empty<T>() : self;
}
}
Now you can write ...
model.FilterSet.Dispositions.EmptyIfNull().Where( ... )
and if model.FilterSet.Dispositions is null, you won't get an exception, but the statement will evaluate to an empty set.
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();