ExecuteScalar null value error - c#

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)

Related

Null value in linq where clause

I'm having an issue where I want to return results where something matches and I get an error if one of the properties I'm trying to match is null.
if (!string.IsNullOrEmpty(searchString))
{
Infos = Infos.Where(
x =>
x.FirstName.ToLower().Contains(searchString) ||
x.LastName.ToLower().Contains(searchString) ||
x.ContractNum.ToLower().Contains(searchString) ||
x.VIN.ToLower().Contains(searchString) ||
x.Claim.InitiatedBy.ToLower().Contains(searchString)
).ToList();
}
If ContractNum or VIN, for example, are null then it throws an error. I'm not sure how to check if one of these are null inside of a linq query.
You can add explicit null checks:
Infos = Infos.Where(
x =>
(x.FirstName != null && x.FirstName.ToLower().Contains(searchString)) ||
(x.LastName != null && x.LastName.ToLower().Contains(searchString)) ||
(x.ContractNum != null && x.ContractNum.ToLower().Contains(searchString)) ||
(x.VIN != null && x.VIN.ToLower().Contains(searchString)) ||
(x.Claim != null && x.Claim.InitiatedBy != null && x.Claim.InitiatedBy.ToLower().Contains(searchString))
).ToList();
You have multiple options, first is to do an explicit check against null and the other option is to use Null propagation operator.
x.FirstName != null && x.FirstName.ToLower().Contains(searchString)
or
x.FirstName?.ToLower()?.Contains(searchString) == true
But I would suggest you to use IndexOf instead of Contains for case
insensitive comparison.
something like:
x.FirstName?.IndexOf(searchString, StringComparison.CurrentCultureIgnoreCase) >= 0)
Checking the property is null or empty before comparing it it's the only way I know
if (!string.IsNullOrEmpty(searchString))
{
Infos = Infos.Where(
x =>
(!String.IsNullOrEmpty(x.FirstName) && x.FirstName.ToLowerInvariant().Contains(searchString)) ||
(!String.IsNullOrEmpty(x.LastName) && x.LastName.ToLowerInvariant().Contains(searchString)) ||
(!String.IsNullOrEmpty(x.ContractNum) && x.ContractNum.ToLowerInvariant().Contains(searchString)) ||
(!String.IsNullOrEmpty(x.VIN) && x.VIN.ToLowerInvariant().Contains(searchString)) ||
(x.Claim != null && !String.IsNullOrEmpty(x.Claim.InitiatedBy) && x.Claim.InitiatedBy.ToLowerInvariant().Contains(searchString))
).ToList();
}
EXTRA: I added a check on the Claim property to make sure it's not null when looking at InitiatedBy
EXTRA 2: Using the build in function IsNullOrEmpty to compare string to "" and nullso the code is clearer.
Extra 3: Used of ToLowerInvariant (https://msdn.microsoft.com/en-us/library/system.string.tolowerinvariant(v=vs.110).aspx) so the lowering action will act the same no matter of the culture.
You could use ?? to replace it with a acceptable value.
(x.ContractNum??"").ToLower()
I would use the null conditional operator ?, this will however, return a nullable bool? so you will need to handle that appropriately.
Some examples on how to do this:
x?.FirstName?.ToLower().Contains(searchString) == true;
x?.FirstName?.ToLower().Contains(searchString) ?? false;
An alternative method to keep the comparison logic in one place to use a sub collection of the properties and check on those:
Infos = Infos.Where(i=>
new[] {i.FirstName,i.LastName,i.ContractNum /*etc*/}
.Any(w=> w?.ToLower().Contains(searchString) ?? false))
.ToList();
(It does read out all properties, but that shouldn't cost much performance and gains much maintainability )

Pattern matching equal null vs is null

From Microsoft new-features-in-c-7-0:
public void PrintStars(object o)
{
if (o is null) return; // constant pattern "null"
if (!(o is int i)) return; // type pattern "int i"
WriteLine(new string('*', i));
}
Whats the diferrence of o == null and o is null?
The o is null is translated to object.Equals(null, o) (you can see it here).
The object.Equals code is written as:
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
so in the end there will be a o == null (the first if). Note that System.Object doesn't define the operator==, so the one used is the one for reference types that is reference equality.
Theorically, by watching the called code, one could think that o == null (with o a System.Object) should be faster than o is null (less operations)... But who knows? :-)
The end result is that, through two different routes, o is null and o == null (with o a System.Object) return the same result.
By looking we can even see that o == null is the same as object.ReferenceEquals(o, null) (with o a System.Object) :-).
the interesting question should be, why doesn't the C# compiler translates the x is null to object.ReferenceEquals(x, null)?. Note that, thanks to how the boxing of nullable types is done, it would work even for:
int? a = null;
if (a is null) { /* */ }
changes to the compiler made this response invalid... If you click on the "here" link you can see it
Since the answer of #xanatos is outdated (but that is only mentioned at the very end) I'm writing a new one, because I wanted to know this as well and researched it.
In short: if you don't overload the == operator, then o == null and o is null are the same.
If you do overload the == operator, then o == null will call that, but o is null won't.
o is null always does the same as ReferenceEquals(o, null), i.e. it only checks if the value is null, it doesn't call any operators or Equals methods.
Longer answer: here is a SharpLab sample that showcases the various ways to check for null.
If you view the result in IL form you see that:
is null and ReferenceEquals result in the same code
o == null will call the overloaded operator==
object.Eqauls(o, null) calls that method
if you comment the operator== in class C you will see that o == null now produces the same code as o is null
The differences between "is" and == is "is" special that it act as == if you compare to value and act as typeof(type) when you compare type of object to type.

Inline If statement - short-circuiting

As I understand and read you can use short circuiting in if statement (&& or ||) in order for second condition not to fire. and if you want both condition to fire you would use single operands (& or |).
So say if I have inline if statement as below :
var test = (MyObject != null || string.IsNullOrEmpty(MyObject.Property)) ? string.Empty : MyObject.Property;
This will throw object reference error if MyObject is null, which in my opinion should not as I am using short circuiting. Can someone please explain this.
You're using the wrong condition. This part:
MyObject != null || string.IsNullOrEmpty(MyObject.Property)
should be:
MyObject == null || string.IsNullOrEmpty(MyObject.Property)
The RHS of an || only executes if the left hand is false. You want it to only execute if MyObject is not null.
EDIT: If you really want the MyObject != null part, you could change the whole thing to:
var test = MyObject != null && !string.IsNullOrEmpty(MyObject.Property)
? MyObject.Property : "";
Note the reversal of the 2nd and 3rd operands of the conditional operator too though.
You should have an == not an !=
var test = (MyObject == null || string.IsNullOrEmpty(MyObject.Property) ? string.Empty : MyObject.Property
Try this:
var test = (MyObject == null || string.IsNullOrEmpty(MyObject.Property)
? string.Empty : MyObject.Property
MyObject != null || string.IsNullOrEmpty(MyObject.Property)
Here you say.
If my object is not null.
or
string.IsNullOrEmpty(MyObject.Property)
Which means that if MyObject is null he will try to execute the second part.
MyObject == null || string.IsNullOrEmpty(MyObject.Property)
This won't throw null exception
That happens because MyObject is null and therefore the first condition is false so the second part must be evaluated to know the whole of the condition. Change the line to this:
MyObject != null && string.IsNullOrEmpty(MyObject.Property)
You should prefer readability instead of line-count, e.g.:
string prop = string.Empty;
if(MyObject != null && MyObject.Property != null)
prop = MyObject.Property;
(the reason for your exception was already explained in other answers)

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 to SQL and Null strings, how do I use Contains?

Here is the query
from a in this._addresses
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
if both properties in the where clause have values this works fine, but if for example, a.StreetAdditional is null (Most of the times), I will get a null reference exception.
Is there a work around this?
I'd use the null-coalescing operator...
(from a in this._addresses
where (a.Street ?? "").Contains(street) || (a.StreetAdditional ?? "").Contains(streetAdditional)
select a).ToList<Address>()
The most obvious one:
from a in this._addresses
where (a.Street != null && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>()
Alternatively you could write an extension method for Contains that accepts a null argument without error. Some might say that it is not so pretty to have such a method, because it looks like a normal method call, but is allowed for null values (thereby setting aside normal null-checking practices).
You must check first if StreetAdditional is null.
Try
where a.Street.Contains(street) || ((a != null) && a.StreetAdditional.Contains(streetAdditional))
This works because && is a shortcut-operator and if a != null yields false, the second expression with the null-value won't be evaluated since the result will be false anyway.
I would create an extension method to return an empty sequence if null and then call contains method.
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
return pSeq ?? Enumerable.Empty<T>();
}
from a in this._addresses
where a.Street.Contains(street) ||
a.StreetAdditional.EmptyIfNull().Contains(streetAdditional)
select a).ToList<Address>()
I don't think SqlServer gave you a null exception. If it did, then this code is clearly not running though LinqToSql (as you've tagged the question).
string.Contains would be translated to sql's like, which has no trouble at all with null values.
Check to make sure that the properties are not null
from a in this._addresses
where (a.Street != null && a.Street.Contains(street)) ||
(a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>()
If the null check is false, then the second clause after the && will not evaluate.
from a in this._addresses
where a.Street.Contains(street) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
You might want to check to make sure the variables street and streetAdditional are not null. I just ran across the same problem and setting them to an empty string seemed to solve my problem.
street = street ?? "";
streetAdditional = streetAdditional ?? "";
from a in this._addresses
where a.Street.Contains(street) || a.StreetAdditional.Contains(streetAdditional)
select a).ToList<Address>()
One thing to note is that the null should be evaluated first.
where (**a.Street != null** && a.Street.Contains(street)) || (a.StreetAdditional != null && a.StreetAdditional.Contains(streetAdditional))
select a).ToList<Address>
()

Categories

Resources