views:

1630

answers:

5

SQLServer int field. Value sometimes null. DataAdapter fills dataset OK and can display data in DatagridView OK.

When trying to retrieve the data programmatically from the dataset the Dataset field retrieval code throws a StronglyTypedException error.

 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public int curr_reading {
        get {
            try {
                return ((int)(this[this.tableHistory.curr_readingColumn]));
            }
            catch (global::System.InvalidCastException e) {
                throw new global::System.Data.StrongTypingException("The value for column \'curr_reading\' in table \'History\' is DBNull.", e);
            }

Got past this by checking for DBNull in the get accessor and returning null but... When the dataset structure is modified (Still developing) my changes (unsurprisingly) are gone.

What is the best way to handle this situation? It seems I am stuck with dealing with it at the dataset level. Is there some sort of attribute that can tell the auto code generator to leave the changes in place?

A: 

If memory serves, you need to mark the row as being edited - using .BeginEdit() or similar - then make your edits and save the row, probably using .EndEdit() or similar. You may want to do a little bit of reading into these methods (they may be on the DataSet, DataTable or DataRow) - my memory is a little hazy.

Hope this helps at least a little bit.

Fritz H
A: 

The dataset will have a boolean property to indicate null.

int curr_reading = ( Iscurr_readingColumnNull) ? 
                   <default_value> : row.curr_readingColumn;
MikeW
Spot on. No Experience with Extension methods but believe it would have failed as trying to use the Dataset Get accessor triggers the error.This 'internal' Datarow test works. Thanks. Bob
Found another field in the parent table, for this field there was no internal null test. Wrote extension method. It worked. Thanks to you all.
+2  A: 
  1. Leave the auto-generated code alone. There's no way to "intercept" it getting generated so any changes you do make are guaranteed to get blown away sooner or later.

  2. .NET (well at least the .NET 2.0 system.data bits) will not convert from DBNull into anything else. This sucks but you can't do anything about it.

  3. Write an extension method called ToNullable() or similar: it can do this:

.

public static Nullable<T> ToNullable(this object x){
    if(x == DBNull.Value)
       return default(T); // return null thing
    else
       return (T)x;
}

then you can do

int? thing = DataRow["column"].ToNullable<int>();
Orion Edwards
This really works. Sad though, that I will loose my strongly typing by using the indexer with the string.
Marcel
+1  A: 

In the typed dataset designer there is the nullvalue property. By default its value is throw exception (hence your generated code) You can set it to the desired default value.. ie. 0. Then it will return 0 instead of an exception. (other code is generated)

VS2008 :This works directly in the dataset designer.

VS2005 : It only works for strings in the designer but you can directly edit the XSD an set the property msprop:nullValue="0"

Julian de Wit
A: 
if(row["curr_reading"] is DBNull){

}else{
    row.curr_reading;
}
chiesa