I start MySQL query going to a list with one value that is a DateTime object. As this list builds it hits a null value and --- DateTimeSqlNullValueException: Data is Null.
First I naively tried using ISNULL, !=NULL, ==NULL... which are not methods of the DateTime object. Then I tried
queryResult.EventTime = rdr.GetDateTime("timeIn");
if (Convert.IsDBNull(rdr.GetDateTime("timeIn")))
{
Console.Write("yeup it's null");
queryResult2.EventTime = DateTime.MinValue;
}
This didn't work either.
Then I though instead of rdr.GetDateTime() I thought maybe using GetString() instead and use the methods for strings to test for null then change it back to a DateTime and set it to DateTime.MinValueso I could address it in the view later on. This seemed like a total cludge and not very elegant. So I have been searching for the one liner that I can test the nullness of rdr.GetDateTime("timeIn"); and set it to DateTime.MinValue
Don't use GetDateTime until you know the value isn't null:
if (rdr.IsDBNull(rdr.GetOrdinal("timeIn"))))
{
Console.Write("yeup it's null");
queryResult2.EventTime = DateTime.MinValue;
}
else
{
queryResult.EventTime = rdr.GetDateTime("timeIn");
}
you can write an extension method which will do the check and so make it a one liner (untested code, but should give you the idea):
public static GetDateTimeOrDefault(this IDataReader dr, string columnName, DateTime defaultValue)
{
int ordinal = dr.GetOrdinal(columnName);
if (dr.IsDbNull(ordinal))
{
return defaultValue;
}
return dr.GetDateTime(ordinal);
}
you can then call this like so:
queryResult.EventTime = rdr.GetDateTimeOrDefault("timeIn",DateTime.MinValue);
you don't need to pass in the default value, but its a good idea to do so, as you then have control from the calling site to specify the value you want if the database field is null, and the calling site is where you will know what value you want. you may not always want DateTime.MinValue, you may want DateTime.Now sometimes for example
Related
i don't know what i'm doing wrong, i'm working on an existing application and i'm creating a unit test for this method.
on the Test Method, i mocked the view and assigned a value on the item
_fakeView.Setup(x => x.Bag.Amount).Returns((decimal)300.32);
(Note that the Amount is string)
and i'm passing the view object to the presenter and initialized
_presenter = new Presenter(_fakeView.Object);
_presenter.InitializeForm();
and on the existing code for initialize, they have a line of code to reassign the values like this:
this._view.Amount = this._view.Bag.Amount.ToString();
when this line run, the this._view.Amount is still null even if this._view.Bag.Amount.ToString() has value.
i even tried setting it directly
this._view.Amount = "asdfgsdf"; but still null
please help
Just because you assign a value something, doesn't mean it can't be null. this._view.Bag.Amount.ToString() has to be returning null.
This means, either this._view is null, this._view.Bag is null, or this._view.Bag.Amount is null, or ToString() is failing somehow. You'll have to check the values and find out where the null is coming from.
Also, if Amount is string why are you using ToString()?
Edit: It is possible that the code for Amount is something like this:
// Get works as expected but set does literally nothing to change the backing field
private string amount = null;
public string Amount
{
get => amount;
set
{
// Do literally nothing
}
}
Or:
// Get will always return null, but set works as expected
prviate string amount;
public string Amount
{
get => null;
set => amount == value;
}
In both examples, Amount will always return null if you're trying to use only the set/get.
Is there a SetAmount(string amount) method you could call?
i found what i'm missing..
_fakeView.SetupAllProperties();
i added this
_fakeView.SetupAllProperties();
before
_fakeView.Setup(x => x.Bag.Amount).Returns((decimal)300.32);
I have a table with a few fields, one of them is a Double type field which can contains null values...
Using ADO and SQLDATAReader I recover that field in a variable. I defined this variable as a: Double, Double?, double, double?... and I got the value (coming from de SQLDataReader) using GetValue (and doing a cast) or using a GetDouble... each one is crashing when the value is null.
The only this is working is defining this variable as a object, but I dont want it. Thinking in advance could be hard times handle this type in my project...
Quote: I have to differentiate the case when this value is 0 or null...
Any idea guys?
Edited:
Object.DoubleValue= (Double?)Datos.GetDouble(1);
Object.doubleValue= (double?)Datos.GetDouble(1);
Not working.
Object.ObjectValue= Datos.GetValue(1);
Working.
Unfortunately there's no out of the box method. But you could tweak it with an extension method like this:
(be aware its just a rough prototype that works in your case, but probably needs some checks and constraints etc)
public static class Helpers
{
public static T GetSmartValue<T>(this SqlDataReader r, int ordinal)
{
dynamic value = r.GetValue(ordinal);
if (value == DBNull.Value)
{
value = null;
return value;
}
return (T) value;
}
}
then in your code
var x = yourReader.GetSmartValue<double?>(1);
I've made an UltraGrid with Infragistics where I have a column of Datetime type with the format HH:mm.
Normally the column is filled with a value like : "15:13". I can edit it and set what I want then save. But if I delete the field it looks like that : "_ : _" then I save my table, I get back an exception "Specified cast is not valid".
This is because I'm trying to save a value which is not set. I would like to know how to handle this exception.
I tried to compare the fiel to "null" but it does not work.
var newDuration = (DateTime)row.GetCellValue(3);
if (newDuration == null)
{
MessageBox.Show("Please set all the fields.");
}
The dataType of the column is System.DateTime, I set the default value to DB (DBNull) and AllowDBNull is Default.
There are two ways to fix the issue:
display a message to the user to ask him to set a value
If the field is empty, set a default value like 00:00
Ask me if you need more info. Thanks !
Typical pattern to try to get value of wanted type without being sure is
var value = someOtherValue as SomeType;
if (value != null)
{
... // value is a correct SomeType here
}
This works for reference types. In case of structures (DateTime is a structure), which are value types, you'll have to check the type prior
var value = row.GetCellValue(3);
if(value is DateTime)
{
var dateTime = (DateTime)value;
... // dateTime is a valid DateTime here
}
My answer doesn't explain why you have the problem, but shows how to avoid having it (which may not be a good idea, but it seems you want that).
If your value can be DBNull, then simply check for it:
var value = row.GetCellValue(3);
if(value != DBNull.Value)
{
var dateTime = (DateTime)value; // it must work now
...
}
Actually I did this :
try
{
newDuration = (DateTime)row.GetCellValue(3);
}
catch
{
row.SetCellValue(3, new DateTime());
newDuration = (DateTime)row.GetCellValue(3);
}
And it works... Thanks all for your help, I will use what you told in my future dev' !
At the wingrid there is a specific event for handling this errors, its datacellerror quite useful and no need of anything else, hope this its helpfull for someone
In an MVC App we are suppose to dynamically load some strings from database. Basically a <string,string> key-value dictionary. Loading each text each time from the database would kill the application, so those texts would normally be pulled from the DB just once and then stored in cache (namely Web.HttpContext.Current.Cache). There are also default texts that are hardcoded and those would be used if nothing was found in the database. To make things more simple I would also put those default texts in the cache.
The logic is as follows:
Try getting the text from cache and return it if it's found.
If there was no text in the cache, try pulling it from the databaseand and if it's found, save it to cache and return it.
If all above failed, use the default text and save it to the cache so no further queries will be made for this particular key.
If I understand it correctly the only way to check if key is set in Web.HttpContext.Current.Cache is by comparing it's value to a null. My problem is, it's not entirely unlikely that the default text will be a null. So if I put that in the cache, I will not know that the key was set and I will try to pull the non-existant value from the database each time the text is needed.
I know I could use an empty string instead of a null, but it's possible that I might need to distinguish between nulls and empty strings for some reason in the near future.
So is there some way to tell if a key is set in the Web.HttpContext.Current.Cache when the value assigned is a null?
StriplingWarrior beat me to the punch, but I agree with what he said: just wrap what you're storing in a complex type so you can do a null check. Normally you'd use Nullable<T> for this, but you can't use a Nullable type for things that are already considered nullable, like strings.
Here's a practical example:
Define a simple wrapper class:
public class CacheEntry<T>
{
public T Value { get; private set; }
public CacheEntry(T value)
{
Value = value;
}
}
And then use it!
System.Web.HttpContext.Current.Cache.Insert("name", new CacheEntry<string>("Marcin"));
var name = (CacheEntry<string>) System.Web.HttpContext.Current.Cache.Get("name");
if (name != null)
{
Console.WriteLine(name.Value);
}
null is highly overused by most C# developers. If you recognize that these values are optional (meaning they may or may not be there), you may want to make your cache entries be of some type that wraps the actual type you're storing. That way, getting a null value means that there is no entry, whereas getting a non-null value that has a null Value property on it means it exists in the cache, but its value is null.
Incidentally, I've been working on a library to represent exactly this sort of wrapper. It's still in its alpha phases at the moment, but at least for this purpose it should be safe to use. You can get it from Nuget under the name "CallMeMaybe".
object result = HttpContext.Current.Cache.Get(key);
if(result != null)
{
return ((Maybe<string>)result).Else(() => null);
}
var value = Maybe.From(GetValueFromDb());
HttpContext.Current.Cache.Add(key, value, ...);
return value;
Another option would be to use MemoryCache directly, which I think is what backs the HttpContext.Current.Cache these days, but which provides additional methods like GetCacheItem.
If you must store a null in something that doesn't distinguish between nulls and key-not-found conditions, store an "active null" object to represent a null you've actually added:
private static readonly object ActiveNull = new object();
public bool GetIfPresent(string key, out object value)
{
object fromCache = Web.HttpContext.Current.Cache.Get(key);
if(fromCache == null)
{
//failed to obtain.
value = null;
return false;
}
if(ReferenceEquals(fromCache, ActiveNull))
{
//obtained value representing null.
value = null;
return true;
}
value = fromCache;
return true;
}
public void AddToCache(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
{
Web.HttpContext.Current.Cache.Add(key, value ?? ActiveNull, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback);
}
I have asp.net form with C#, where is I am taking user information to insert in the database as usual by using Linq. well. Where as I am taking Date of birth also from the user, but if user skip to fill date text box from ui, then I am getting date like '01/01/0001' something like this, which certainly database security would not allow to store it.
So I need to check somewhere in my code that it is null or in this (above given) format. If it is null or in format '01/01/0001' then what exactly I have to do? I don't have any default
value for dates.
So what is the standard way to handle if date is null (but not mandatory).Please guide me. So many times I found myself in trap while handling null for various types.
Edited
see what i did seems it working here. but i don't think so this is standard way:
DateTime? otxtDOB = new DateTime();
if (!string.IsNullOrEmpty(DOB))
{
if (Convert.ToDateTime(DOB) != DateTime.MinValue)
{
otxtDateOfPurchese = Convert.ToDateTime(Convert.ToDateTime(DOB).ToString("dd-MMM-yyyy"));
}
else
{
otxtDOB = null;
}
}
Please confirm me is this right way ?
Making the date property Nullable (i.e. a "DateTime?") should allow it to actually be null if the user hasn't set it. (And provided your database column will allow nulls, it can be stored as null in the database)
Otherwise it's going to default to DateTime.MinValue which is what you're seeing here. And you'll have to explicity test for DateTime.MinValue when adding to the database.
DateTime is a value type (like a number), so you can't assing a null value to it. Mane people use DateTime.MinValue or DateTime.MaxValue instead, but I prefer to use nullable types:
DateTime? nullableDate;
dateSample.Value = null;
you can do some thing like this C# have some features like nullable type you can make use of
this it will save you some piece of code it will be more robust too.
Public int InsertData(int? ouId)
{
chkValue = ouId.HasValue ? ouId.Value : 0;
}
You have the option of using Nullable<DateTime> (alias DateTime?). This makes you able to handle the date as null throughout your application.
However, personally I am not to found of nullables and would prefer this second path: You can use DateTime.MinValue (which is 01/01/0001) as a meaningful constant in your application and the check for DateTime.MinValue in your data access layer.
The database, if it is an SQL Server and the field is of type smalldatetime, would overflow and throw an exception if you tried to save DateTime.MinValue. Null however, may well be stored in the database for any type.
This is how you can parse your strings into nullable types:
private delegate bool TryParseDelegate<T>(string s, out T t);
private static T? TryParseNullable<T>(string s, TryParseDelegate<T> tryParse) where T : struct
{
if (string.IsNullOrEmpty(s))
return null;
T t;
if(tryParse(s, out t))
return t;
return null;
}
with usage:
var nullableDateTime = TryParseNullable<DateTime>("01/01/0001", DateTime.TryParse);
use
DateTime dt;
if(DateTime.TryParse(DatetImeValue.Tostring(),dt)) // datetimevalue is your db value
{
datetimeproperty = dt; // in your class declare it as DateTime? datetimeproperty
}
else
{
datetimeproperty = null;
}
While displaying check for null, if its null set it empty.
[Update]
Do one thing, Keep the property nullable. In your database. Set field to allow null and in the parameter user #DateTimeParam = null.
OR A QUICK WORKAROUND MAKE THE DATABASE FIELD AND PARAMETER VARCHAR INSTEAD OF DATETIME, IN PARAMETER PASS DATETIMEVALUE.TOSHORTDATESTRING() AND ALSO CHECK IF USER SKIPS
PUT STRING.EMPTY IN PARAMETER. IN THIS MANNER IT WILL BE EASY TO YOU TO DISPLAY DATE AND TIME. YOU NEED NOT CAST OR WIPE OFF THE TIME PART IF YOU DO NOT NEED IT
obj.BirthDate = Convert.ToDateTime(string.IsNullOrEmpty(txtBirthDate.Text.ToString()) ? System.Data.SqlTypes.SqlDateTime.MinValue.Value : Convert.ToDateTime(txtBirthDate.Text.ToString()));
You can use this while passing to database.
object datetimeObj = null;
if (datetimefromUI == DateTime.MinValue) // This is put in the DateTime object by default
datetimeObj = DBNull.Value;
else
datetimeObj = datetimefromUI;
// Post datetimeObj to parameter in database...