I want to check the following field in the datatable against null :
r.Field<int>("prod_type")
if (r.Field<int>("prod_type") != null &&
!string.IsNullOrEmpty(r.Field<int>("prod_type").ToString()))
but I get the following exception :
Specified cast is not valid.
How to check the integer value in the datatable against null or empty ?
The Field extension method supports nullable types. Use HasValue to check if a nullable is not null:
if (r.Field<int?>("prod_type").HasValue)
The error you are getting is indicating that the field in the datatable is not of type int. If it is of type int it can't hold null value, instead you can try int? which is Nullable.
r.Field<int?>("prod_type") != null
If prod_type is indeed an int field in the database, try doing it like this:
if (r.Field<int?>("prod_type") != null)
Related
I am trying to read nullable values from a database. Right now my code is converting null values to false. How can I modify my code to allow for null values?
Ap1ExamTaken = dr["AP1_ExamTaken"] != DBNull.Value && Convert.ToBoolean(dr["AP1_ExamTaken"]),
I would like values that are null to be shown as null and not false.
You could use the conditional operator here, to set it to null if the value is DBNull.Value, or a non-nullable value otherwise:
Ap1ExamTaken = dr["AP1_ExamTaken"] == DBNull.Value ? null : (bool?) dr["AP1_ExamTaken"];
Note that this will throw an exception if dr["AP1_ExamTaken"] is a non-boolean, non-DBNull type, which I suspect is what you want.
You could write it more compactly as:
Ap1ExamTaken = dr["AP1_ExamTaken"] as bool?
... but then you'll end up with a null value if the value is some other type (a string, an integer etc) which I'd generally be alarmed about. (If my data doesn't have the shape I expect, I want to know ASAP.)
I am adding new extension method for checking null value for any object on following criteria:
Should return true if value for class object is null
Should return true if object is of type string and having value null or Empty
Should return true if object is of type DateTime and having Min value.
Any other condition for null need to check.(Please suggest if required.)
Here is IsNull() extention method:
public static bool IsNull(this object obj)
{
if (obj == null || obj == DBNull.Value)
return true;
if (obj.GetType() == typeof(string))
return string.IsNullOrEmpty(obj.ToString());
if (obj.GetType() == typeof(DateTime))
{
DateTime _dateValue = DateTime.MinValue;
if (DateTime.TryParse(obj.ToString(), out _dateValue) && _dateValue == DateTime.MinValue)
return true;
}
return false;
}
Now my question is:
Do I need to add check differently for Value and Reference type
object?
Does this extension method handle all type of null check for any
object?
Any suggestion or improvement need to add in extension?
Do I need to add check differenty for Value and Reference type object?
Value types can not be null.
Does this externtion method handle all type of null check for any object?
It looks like (except value types)
Any suggestion or improvement need to add in extention?
As I said value types cannot be null, so you can add an extra condition to check whether the type is value type or not,if so you can return false
if(obj.GetType().IsValueType) return false;
By the way if you write this before the DateTime check,your DateTime condition will become unreachable.It doesn't make sense anyway but it's your choice.If you want to return true when the value equals to DateTime.MinValue it's completely up to you.
A few observations:
1) A value type will never be null. When called on a value type.. it will be boxed to an object.. and won't be null (unless you wrap it in a Nullable<T>).
2) Your method no longer checks for null.. it also checks for a minimum value and empty strings. An empty string is not null - its an empty value. A minimum value is not null.. its a value. It has too much responsibility here and should be renamed.
3) Given what I've said above.. you could just simply do this instead of writing your own function:
if (variable == default(variable.GetType()))
Since that checks for the default of all types.. value types such as DateTime, int, and classes for null. Then, your only other specific check is for DBNull.Value.
I've got problems at this line:
int? nextLevel = (from p in cd.Objective
where p.Parent_ObjectiveID == null
select p.ObjectiveID).Max() + 1;
The error specifies:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
How can I fix it?
UPDATE:
But p.Parent_ObjectiveID is int? datatype. It can be null.
The objectiveID is of type which is not nullable. So whats the point of checking it for NULL type? You never can assign a null value to a non nullable value. May be use objectiveID? instead..
Basically, p.Parent_ObjectiveID cannot be null, (i.e. a "non-nullable" type). So there is no need to check if it is a null or not.
So to fix it, get rid of the where part, or change it from null, to an System.Int32 value.
I have CustomerID declared as
int? CustomerID=null;
I am checking null values while reading DataReader
Id = reader["CustomerId"] is DBNull ? null :Convert.ToInt32(reader["CustomerID"]);
It is throwing
Type of conditional expression cannot be determined because there
is no implicit conversion between '<null>' and 'int'
What is the problem with the Conversion?
I think you need to do it this way:
if(! reader.IsDBNull(reader.GetOrdinal("CustomerId"))
{
Id = Convert.ToInt32(reader["CustomerID"]);
}
else
{
Id = NULL;
}
You need to use the .IsDBNull method on the reader to determine ahead of time if a column is NULL - if it is, don't even read the value from the reader.
Change your conditon to
reader["CustomerId"] == DBNull.Value
A ?: conditional expression cannot evaluate to two different types on the true and false condition. I think a cast (int?)null should work.
The problem (assuming that Id is declared properly) is that the conditional statement infers the result type from the true result. In your case, that type is null. It then will try to cast the second type to the same as the first...and there is no cast from int to null.
The solution is to cast the true expression to the desired type:
Id = reader["CustomerId"] == DBNull.Value ?
(int?) null :
Convert.ToInt32(reader["CustomerID"]);
Try this
Id = reader["CustomerId"] is DBNull ? (int?)null : Convert.ToInt32(reader["CustomerID"]);
the types of both parts of the ?: need to be explicit
What's happening is your code is incorrectly evaluating and trying to do the Convert function.
Its readding reader["CustomerId"] is DBNull which it isn't its really a DBNull.Value so then it attempts to do Convert.ToInt32("<null>") and crashes. You need to fix your if statement, and add a (int ?) cast.
It should be:
Id = reader["CustomerId"] is DBNull.Value ? (int?) null :Convert.ToInt32(reader["CustomerID"]);
I have an Oracle data table fetching columns that be null. So I figure to keep the code nice and simple that I'd use the ?? operand. AlternatePhoneNumber is a string in my C# model.
AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""
However, even with that code I still get the error.
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
I know what the error means but why is ?? not usable on DBNull? Isn't null and DBNull essentially the same?
Thank you.
The ?? operator only applies to actual nulls.
null and DBNull.Value are not the same; DBNull.Value is simply a placeholder object.
Also, that exception is coming from inside the AlternatePhoneNumber property, before your ?? operator executes. (Your code doesn't have a cast).
If customer is a row in a typed dataset, change the column's NullValue property in the designer.
null and DBNull are not the same. System.DBNull is an actual object.
The problem is that AlternatePhoneNumber is a string. DBNull is not.
Try this instead:
AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
Do this:
public T IfNull<T>(object o, T value)
{
return (o == DbNull.Value) ? value : (T)o;
}
DBNull is a type with a single value, and is not the same as a null string reference, which is why you can't use ??. You could do this however:
string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
As other replies state, null means a reference that refers to no object, while DBNull is a class supplied by ADO.NET to indicate when a field or value is NULL at the database (or in a DataTable).
While you can use the conditional (ternary) operator (?:) to do what you want:
AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull
? ""
: customer.AlternatePhoneNumber;
I tend to wrap this up in an extension method:
static class NullExtensions
{
public static T WhenNull<T>( this object value, T whenNullValue )
{
return (value == null || value is DBNull)
? whenNullValue
: (T)value;
}
}
which I find makes the code easier to read and understand.
AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
DBNull is NOT a real "null".
The "??" - operator detects only null - references, not objects that emulate "null" behavior.