I can't figure out where this NullReferenceException is coming from - c#

EDIT Upon further reflection I decided to amend my answer below to reduce the possibility of misinterpretation of the problem.
I am getting a NullReferenceException on this IEnumarable LINQ query:
designations.ForEach(desg =>
desg.ModifiedBy.UserName = userNames.SingleOrDefault(name =>
desg.ModifiedBy != null && name.Id == desg.ModifiedBy.Id) != null ?
userNames.SingleOrDefault(name => name.Id == desg.ModifiedBy.Id).UserName :
"Not Available");
My best guess at the moment is that it comes from the following statement on the third line of the code above:
desg.ModifiedBy != null && name.Id == desg.ModifiedBy.Id
and the runtime is throwing a NullReferenceException on desg.ModifiedBy.Id. However, I "know" that c# truth-ness evaluations short-circuit (see, e.g., || Operator). Here, if desg.ModifiedBy == null then we should never get to evaluate name.Id == desg.ModifiedBy.Id. Nonetheless, this seems to be happening. Is this possible?

I think you are getting null at value assignation
desg.ModifiedBy.UserName = userNames.SingleOrDefault(name =>

Related

Null value is still evaluated after testing it with condition

I have the following LINQ query:
houses.Where(x =>
x.A && user.B
||
(x.Address == null || user.Address == null ? false : x.Address.CountryCode == user.Address.CountryCode
))
I get an error when user.Address is null in:
user.Address.CountryCode
To avoid that I tried to use:
x.Address == null || user.Address == null
But it seems user.Address.CountryCode is still evaluated.
How can I avoid that?
It's definitely EF Core 3.0 query translator defect.
For now (and in general) you can avoid it by not using conditional operator ?: for criteria expressions which need to be converted to SQL query parameters (like your user.Address.CountryCode), but the equivalent logical binary expressions.
e.g. instead of
(x.Address == null || user.Address == null ? false : x.Address.CountryCode == user.Address.CountryCode)
use the equivalent
(x.Address != null && user.Address != null && x.Address.CountryCode == user.Address.CountryCode)
Personally I find this logic confusing. You might try:
( (x?.Address?.CountryCode != null && user?.Address?.CountryCode != null) ? x.Address.CountryCode == user.Address.CountryCode : false
If that doesn't work then there is something very odd going on with the Address or CountryCode properties! Probably and entity framework issue.

Null reference exception being thrown in EF LINQ query if-clause

I couldn't find the exact words to explain what's happening, so if this is a duplicated question, I apologize.
I tried to do a quite simple AND condition if-clause inside a LINQ Query, in order to check if an object is null and then verify if its property is equal or not the column I wanted to compare.
The code:
public IEnumerable<Plan> GetPlans(Plan plan)
{
return _context.Plans.Where(e =>
e.Situation == plan.Situation &&
e.Notes.Contains(plan.Notes) &&
(plan.Excercise != null && plan.Exercise.Year > 0 ? e.Exercise.Year == plan.Exercise.Year: true)).ToList();
}
I've already done this kind of check a dozen times before in .NET 4.5, without having any kind of issue.
But now, in the first .NET Core 2.0 project I'm working on, I had the following error:
An exception was thrown while attempting to evaluate a LINQ query parameter expression. To show additional information call EnableSensitiveDataLogging() when overriding DbContext.OnConfiguring.
The inner exception is clearer: NULL REFERENCE EXCEPTION.
After some tests, I found out that the error happens when plan.Exercise comes null, even if I try to avoid the exception by checking at first if it's null or not.
If I try to do the same check directly in Immediate Window, it returns "false", as it should be.
Am I missing something here? It could be an EF bug? Any particular reason why this works in .NET 4.5, for example, and not in .NET Core 2.0?
Thanks in advance.
UPDATE
Ivan's solution did the job:
Rewrite ? : constructs with equivalent ||
plan.Excercise == null || plan.Exercise.Year <= 0 || e.Excercise.Year == plan.Exercise.Year
It sounds like this might be a bug in EF Core (but I don't know this for sure).
One thing you might try is to fail fast if the base requirements of plan are not met, and more importantly, instead of using the ternary operator, use the traditional comparison operators along with parenthesis:
public IEnumerable<Plan> GetPlans(Plan plan)
{
if (plan == null) return new List<Plan>();
return _context.Plans
.Where(e =>
e.Situation == plan.Situation &&
e.Notes.Contains(plan.Notes) &&
(plan.Exercise == null ||
plan.Exercise.Year <= 0 ||
e.Excercise.Year == plan.Exercise.Year))
.ToList();
}
To avoid this issue, make sure that you are not evaluating on null object.
var exercice = await _repositoryExercice.FirstOrDefaultAsync(i => i.IsCurrent);
var depenses = _repositoryDepense.GetAll()
.Where( e => e.ExerciceId.Equals(exercice.Id))
.WhereIf(AbpSession.TenantId.HasValue, m => m.TenantId.Value.Equals(AbpSession.TenantId.Value))
.ToList();
The issue was causing by this line .Where( e => e.ExerciceId.Equals(exercice.Id)) because the variable exercice is null.
Best practice, I replaced that line by this :
...
.WhereIf(exercice != null, e => e.ExerciceId.Equals(exercice.Id))
...
how about simplifying your code into something like
public IEnumerable<Plan> GetPlans(int year)
{
return _context.Plans
.Where(e => e.Excercise.Year == year)
.ToList();
}

ExecuteScalar null value error

This is my code..
object o = DBExecuteScalar(myQuery);
if ((int.parse(o.ToString())) <= 2 || (o is null))
{
// my task....
}
In this code, 'o is null' part is giving error. Any help how to deal with these both conditions in single if statement.. What I want is that the value of o should be (null,0,1,2).
Any help ??
In C#, the is operator checks for type equality. You need to check for null as o == null:
object o = DBExecuteScalar(myQuery);
if ((o == null) || (int.parse(o.ToString())) <= 2)
{
// my task....
}
You also need to check for null before you try to perform any actions on it
when you reverse the conditions in the if, then it should work.
In your case the ToString is called first on object o. But because o is null this will result in an exception.
When you reverse the order of your conditions, then the nullcheck will be first. The second part of the or (||) is only evaluated when the first part is false. This will prevent the exception from occurring
With || operator first condition is evaluated first - you want to check if is null first.
Also the int.Parse is not necessary. As RGraham mentioned is null is not a proper way how to check for null.
if (o == null || o == DBNull.Value || (int)o <= 2)

Left outer join , Object reference not set to an instance of an object

I am trying to perform left outer join on 2 objects and getting an error : Object reference not set to an instance of an object.
The objects look like that
var deliverables = OCHART.GetACAPValues(organization, ReportingPeriod, FiscalYear, "(09-10.10a) Outreach Significant").ToList();
var references = (from rf in OCHART.References where rf.RefType.Equals("09-10.10a") && rf.Comments.Equals("2") select rf).ToList();
In which deliverables might often return 0 records. Unfortunately I cannot just go and join two tables from database so deliverables must be an object.
Can somebody please point me in the right direction
Thanks,
My code is
var items = (from rf in references
join pt in deliverables on rf.Description equals pt.b into prt
from x in prt.Where(prt2 => prt2.a.Equals(audience)).DefaultIfEmpty()
where rf.RefType.Equals("09-10.10a") && rf.Comments.Equals("2")
select new
{
audience = (string)(audience == null ? "" : audience),
RefType = (string)(rf.RefType == null ? "" : rf.RefType),
RefOrder = (int)(rf.RefOrder == null ? 0 : rf.RefOrder),
refName = (string)(rf.Description == null ? "" : rf.Description),
collumn_attr = (string)(x.b == null ? string.Empty : x.b),
value = (int)(x.ACAP == null ? (int?)null : x.ACAP)
})
.OrderBy(o => o.RefOrder)
.Take(9)
.ToList();
EDIT:
After some more debuging it appears that I get error on following lines in my code
collumn_attr = (string)(x.b == null ? string.Empty : x.b),
value = (int)(x.ACAP == null ? (int?)null : x.ACAP)
I noticed even when I have values (added for testing) in deliverables and when values are matching the query will execute properly, but when there is no match in deliverable that's when I get the error message.
The issue is probably with handling the null values.
I think x is null and is causing a NullReferenceException in the following lines:
collumn_attr = (string)(x.b == null ? string.Empty : x.b),
value = (int)(x.ACAP == null ? (int?)null : x.ACAP)
This judgment is based on the from x in line's DefaultIfEmpty() call, typical of left-outer-joins.
In database code, you would write something like x.ACAP == null to detect the case where there was no matching join element. If you change this replace the 'x.property == null' checks with "x == null" checks, I suspect your problem will clear up.
There's still the problem with the second line - you're going to get an exception at run-time if you try to cast the value (int?)null to an integer. Using a meaningful default int value such as 0 in the case that x == null will clear that up.
If you step through your code, before the query is executed do you actually see "deliverables" and "references" being populated with data ?
Investigate all child tables/properties you're using in your query. The reason you're getting that error is most likely because one of the properties you're using while comparing is null.
.RefType .Comment for example.
Maybe .RefType is null and it's having problems sorting at the end. Difficult to say without seeing what's in those two collections.
Added after your comment:
Note that it's better not to use .Equals() when your variable could be null. Use == instead. Reference: http://www.dotnetperls.com/string-equals
Also imagine that (x.ACAP == null ? (int?)null : x.ACAP) returns a null.
You're casting that whole thing as an int : value = (int)(x.ACAP == null ? (int?)null : x.ACAP). Casting null as n int will obviously fail
Just for the record, the new Null-conditional operators in C# 6.0 could be used like this:
collumn_attr = x?.b ?? string.Empty,
value = x?.ACAP

Linq where column == (null reference) not the same as column == null

I came across a rather strange problem with linq-to-sql. In the following example,
var survey = (from s in dbContext.crmc_Surveys
where (s.crmc_Retail_Trade_Id == tradeId) && (s.State_.Equals(state))
select s).First();
If tradeId is null, it doesn't behave as if I had specified null specifically like this instead,
var survey = (from s in dbContext.crmc_Surveys
where (s.crmc_Retail_Trade_Id == null) && (s.State_.Equals(state))
select s).First();
Which is my desired behavior. In fact it doesn't return anything unless both values are non-null. I can't figure out how to accomplish this short of several different linq queries. Any ideas?
Change where (s.crmc_Retail_Trade_Id == tradeId)
to
where (s.crmc_Retail_Trade_Id == tradeId ||
(tradeId == null && s.crmc_Retail_Trade_Id == null))
Edit - based on this post by Brant Lamborn, it looks like the following would do what you want:
where (object.Equals(s.crmc_Retail_Trade_Id, tradeId))
The Null Semantics (LINQ to SQL) MSDN page links to some interesting info:
LINQ to SQL does not impose C# null or
Visual Basic nothing comparison
semantics on SQL. Comparison operators
are syntactically translated to their
SQL equivalents. The semantics reflect
SQL semantics as defined by server or
connection settings. Two null values
are considered unequal under default
SQL Server settings (although you can
change the settings to change the
semantics). Regardless, LINQ to SQL
does not consider server settings in
query translation.
A comparison with the literal null
(nothing) is translated to the
appropriate SQL version (is null or is
not null).
The value of null (nothing) in
collation is defined by SQL Server;
LINQ to SQL does not change the
collation.
Another option to solve this, as I ran across this problem as well.
where (tradeId == null ? s.crmc_Retail_Trade_Id == null : s.crmc_Retail_Trade_Id == tradeId)
Not sure on this one, but I suspect when linq-to-sql translates that to an sql query string you get a slightly different expression specifying null directly such that at some point you end up comparing NULL to itself, and NULL=NULL is defined to be false.
I am not familiar with Linq, however in general:
NULL represents a missing, unknown, or undefined value. Strictly speaking, a variable cannot equal NULL; low-lvel languages which provide this construct usually do so as a convenience because there is no easy alternative -- at a higher level it's usually better to rely on ISNULL, defined, or whatever features your language supplies.
One undefined variable is not equal to another undefined variable (and the same applies to NULL == NULL). Joe Celko has a good example of writing a query to find all people whose hair colour matches the colour of the vehicle they drive. Should this query match a bald man who walks everywhere?
It's better to make sp for this purpose because linq will perform iteration it takes while for your assistance if you are using linq.
var c = lstQ_Buffer.Where(q => (((semesterId == 0 || semesterId == null ? q.fkSemesterId == null : q.fkSemesterId == semesterId) && (subjectSpecialtyId == 0 || subjectSpecialtyId == null ? q.fkSubSpecialtyId == null : q.fkSubSpecialtyId == subSpecialtyId) && (subTopicId == 0 || subTopicId == null ? q.fkSubTopicId == null : q.fkSubTopicId == subTopicId)) && (q.fkProgramId == programId && q.fkYearId == yearId && q.fkCourse_ModuleId == courseModuleId && q.fkSubject_SpecialtyId == subjectSpecialtyId && q.fkTopicId == topicId && q.fkDifficultyLevelId == diffucultyLevelId))).ToList();

Categories

Resources