none
Getting StrongTypingException from MS generated code RRS feed

  • Question

  • When accessing a row I am getting StrongTypingException error.

    The field in the database is set to allow nulls

    The properties in the xsd are set to to allow nulls

    In the generated code I have:

          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
          [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
          public string FNM {
            get {
              try {
                return ((string)(this[this.tablePeople_Intl.FNMColumn]));
              }
              catch (global::System.InvalidCastException e) {
                throw new global::System.Data.StrongTypingException("The value for column \'FNM\' in table \'People_Intl\' is DBNull.", e);
              }
            }
            set {
              this[this.tablePeople_Intl.FNMColumn] = value;
            }
          }
    
    
    Obviously wrong as null is an allowed value.

    Do I have to go through the generated code and change the hundreds of places where this occurs and if so how do I keep VS from trashing my changes since it is in the autogenerated code?

    Thanks,

    Glen

     

     

    Wednesday, November 17, 2010 9:24 PM

Answers

  • Here's the thing with DBNull in DataSets and why the generated code throws an exception: generic generated code can't know what you want to do if there's a DBNull: do you want to default it to something or leave it as DBNull? If you want to default it to something, then what? So, instead of any of that, it simply throws an exception.

    Now, to handle that problem, you have a couple of options (modifying the generated code is NOT one of them):

    1) You can use the IsMyFieldNull() method:

    "Click OK to Remove \n"+ 
    row.IsFNMNull() ? "" : row.FNM.ToString()+" "+
    row.IsLNMNull() ? "" : row.LNM.ToString()
    

    2) You can use the untyped syntax:

    "Click OK to Remove \n"+ 
    row["FNM"].ToString()+" "+
    row["LNM"].ToString()
    

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by wg_self Monday, November 22, 2010 7:26 PM
    Saturday, November 20, 2010 7:12 PM

All replies

  • Hello Glen,

     

    The generated code is normal (at least it is the same as my side). Would you please tell me how did you get the exception? Is there any code snippet?


    Best Regards,
    Roahn Luo
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Thursday, November 18, 2010 6:38 AM
  • The Following call works fine if the FNM field is not null :

    MessageBoxResult rstlDeleteOK = MessageBox.Show("Click OK to Remove \n"+ row.FNM.ToString()+" "+row.LNM.ToString(),"Delete Person Verification",MessageBoxButton.OKCancel);
    
    
    But throws an exception with this message:

    "The value for column 'FNM' in table 'People_Intl' is DBNull."

    When FNM is null which is an allowed condition

     

    Thursday, November 18, 2010 1:17 PM
  • Here's the thing with DBNull in DataSets and why the generated code throws an exception: generic generated code can't know what you want to do if there's a DBNull: do you want to default it to something or leave it as DBNull? If you want to default it to something, then what? So, instead of any of that, it simply throws an exception.

    Now, to handle that problem, you have a couple of options (modifying the generated code is NOT one of them):

    1) You can use the IsMyFieldNull() method:

    "Click OK to Remove \n"+ 
    row.IsFNMNull() ? "" : row.FNM.ToString()+" "+
    row.IsLNMNull() ? "" : row.LNM.ToString()
    

    2) You can use the untyped syntax:

    "Click OK to Remove \n"+ 
    row["FNM"].ToString()+" "+
    row["LNM"].ToString()
    

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by wg_self Monday, November 22, 2010 7:26 PM
    Saturday, November 20, 2010 7:12 PM
  • Hi Glen,

    Have you tried Bonnie's suggestion, does it work for you?


    Best Regards,
    Roahn Luo
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Monday, November 22, 2010 5:43 AM
  • Bonnie,

    Thank you! I was not aware that one could use the untyped syntax to retrieve from a typed dataset without triggering the error.

    I still consider it an error, as the field is set to allow nulls so... when there is a null in the database I want a null returned. I don't see why VS has a problem with that. Every database I have worked for the last twenty plus years allows nulls to be an acceptable value(or lack thereof) in an otherwise typed field. I have no problem with needing to set it to return a different value if I want it to,( replace null with a space for example) but without that just return what is there ie. NULL

    Oh for the 'good old days' when Microsoft actually documented their product. :-)

    Thanks again,

    Glen

     

    Monday, November 22, 2010 7:26 PM
  • Glen,

    Thank you! I was not aware that one could use the untyped syntax to retrieve from a typed dataset without triggering the error.

    The error is only triggered because of the generated code in the Typed DataSet. As you can see now, the untyped DataSet does not throw an exception. As I mentioned in my previous post, the code generated for the property's get in a Typed DataSet can't know what you want to do if there's a DBNull: do you want to default it to something or leave it as DBNull? If you want to default it to something, then what? So, instead of any of that, it simply throws an exception. That really isn't a bad thing to do.

    I still consider it an error, as the field is set to allow nulls so... when there is a null in the database I want a null returned. I don't see why VS has a problem with that. Every database I have worked for the last twenty plus years allows nulls to be an acceptable value(or lack thereof) in an otherwise typed field. I have no problem with needing to set it to return a different value if I want it to,( replace null with a space for example) but without that just return what is there ie. NULL

    A DBNull is still returned, and it is still valid to have such a value in your data. You just have to know how to properly handle it. You can leave it as DBNull and it will be properly displayed in bound TextBoxes, etc as empty ... but you can't assign it to an int variable, for example, an int can't handle that. This DBNull is not the same as nullable types, even if you used a nullable int in your DataSet (I have not played around with nullable types in DataSets yet).

    Look at it this way ... the data in your DataRow is stored as an object, and that's why it can contain another object, DBNull. It can also contain an int or a bool, for example ... but they are all stored in an object. When you create a Typed DataSet, those objects are exposed as properties of the correct type. An int property cannot be a DBNull object, it's as simple as that. That's why you have to use the untyped syntax to get to that DBNull object.

    Anyway, I hope this has been helpful.  ;0)


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Friday, November 26, 2010 4:13 PM