none
Creating a typed dataset table's row RRS feed

  • Question

  • I need to create a new row with the columns intialized with their default values. I have a typed dataset and table (TableAdapter) and I want to create a row. I do not want to add the row; that will be done later. I know I can create a row using the TableAdapter's new row function but that does not initialize the columns, correct? In the sample in How to: Add Rows to a DataTable a row is created by the TableAdapter's new row function but then the columns are assigned values; I need for the row to be created with default values only. I can write the code myself, but the purpose of a typed dataset is to be able to avoid details such as that.

    Sam Hobbs
    SimpleSamples.Info
    Tuesday, December 20, 2011 9:10 AM

All replies

  • MyDataSet.MyTableRow newRow = ds.MyTable.NewMyTableRow();
    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Thursday, December 22, 2011 5:53 AM
  • Thank you, Bonnie, but it is not working. I create a row for the table using NewMyTableRow (actually it is NewTable1Row). If I look at the new row by setting a breakpoint, the debugger says that there are errors with the fields; errors such as InvalidCastException. If I ignore the errors and continue, then later I get the error that a field does not allow nulls. The field is an integer and it is the primary key. It is true that the field does not allow nulls, but I expect ADO to initialize the field to its default value. Do I misunderstand?



    Sam Hobbs
    SimpleSamples.Info
    Thursday, December 22, 2011 7:36 AM
  • Hi,

    there are different issues here:

    - if you try to read the value of a nullable field, and the field contains a dbnull.value, it will give you an error; you're supposed to check first with the Is<FieldName>Null property.

    - by default, the default value of an integer primary key is dbnull (select the filed in the dataset, look in the properties window under Defaultvalue), even though the field does NOT allow DBNull. It's up to you to determine a value, unless you use the autoincrement feature.

    In my experience, it is almost always nescessary to have some code that initializes values for newrows, especially if foreign keys are involved.


    Regards, Nico
    Thursday, December 22, 2011 8:27 AM
  • Nico, please read my question. I said "create a new row with the columns initialized with their default values". You are explaining why it works the way it is working. I am asking how to get the behavior I described. If you know absolutely for sure that there is nothing in ADO .Net to do that, then you can say that but if there is any possibility that something like that does exist but you are not aware of it then please do not assume it does not exist. So go ahead and reply, but if I don't reply again then please don't assume that I am agreeing with you.

    Bonnie, you have been helpful and tolerant and patient with me in the past. I won't ignore you.



    Sam Hobbs
    SimpleSamples.Info
    Thursday, December 22, 2011 9:10 AM
  • Frankly,

    i find the tone of your response offensive.


    Regards, Nico
    Thursday, December 22, 2011 9:21 AM
  • Nico, at least Sam said "please" a lot. LOL!

    Sam, if you specify defaults in the DataSet designer (or in the XML of the XSD), those defaults will show up when you create a new row in the DataTable ... as long as you use the correct methods for creating the new row. Like this:

    MyDataSet.MyTableRow row = ds.MyTable.NewMyTableRow();
    string x = row.MyFirstStringDefault;
    int y = row.MyFirstIntDefault;
    
    // then add the new row to the DataTable
    ds.MyTable.AddMyTableRow(row);
    
    // you can also add a new row with one statement
    ds.MyTable.AddMyTableRow(ds.MyTable.NewMyTableRow());
    

    Hope this helps ... =0)


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Thursday, December 22, 2011 4:06 PM
  • Thank you, Goddess.

    Let us say that we have a bound DataGridView, as in my article Database Table Update in a DataGridView without Writing Code. The system (ADO .Net or .Net or something) somehow creates a new row when data is filled into the DataGridView new row (typically at the bottom of the DataGridView).

    Let us say that we need a separate form for entering data for new records; it is not needed for updates, just for new records. We can, in the Data Sources window, change the data source so that a detail view ("view" is not the correct term but I do not know what is) is created and then drag that to the new record form. If we do that however, then when the new row is added to the table, the DataGridView data needs to be cleared and filled again to get the new record in the DataGridView. To avoid that, we need to use the same TableAdapter for adding the new row. That is done somehow when data is filled into the DataGridView new row but before the row is added to the table. I am looking for that; at least a functional equivalent.



    Sam Hobbs
    SimpleSamples.Info
    Friday, December 23, 2011 4:34 AM
  • Sorry Sam ... I don't use TableAdapters. I don't believe in tightly-coupling my DataSet to a database. I also don't believe in having any data access stuff in the form, which drag-and-drop programming seems to promote.

    Anyway, one way around the above problem is to set the grid's .AllowUserToAddRows property to false and have a button for adding new rows instead. Then add as I showed above.

    And, actually, I still may not have helped you any because I'm not sure what you mean by this:

    If we do that however, then when the new row is added to the table, the DataGridView data needs to be cleared and filled again to get the new record in the DataGridView. To avoid that, we need to use the same TableAdapter for adding the new row. That is done somehow when data is filled into the DataGridView new row but before the row is added to the table.

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Friday, December 23, 2011 4:26 PM
  • Thank you, Bonnie. I agree with the concept of not using the form as a container. I am surprised that Microsoft leads developers in that direction as much as they do. I am experienced with Visual C++ and MFC where there is more support of deriving from controls instead of creating event handlers in the form's (window's) class; the owner of the controls. I have looked at your web site and now I remember that you don't like things like TableAdapters but I think I did not realize that it is because of what you say here.

    In this situation, if the TableAdapter were separate from the form it would likely make this problem easier.

    As for the part that you quoted, I am saying that if I bind the table to a second form and then update the data in the second form then the first form is not automatically updated with the new data. So if TableAdapters were designed to exists separately from a specific form then it would be easier to use one TableAdapter in multiple forms.

    Oh, so perhaps that is a clue; it is possible to create an instance of a TableAdapter that does not exist in a form. I will try something like that.

    I know that TableAdapters are older technology and that the Entity Framework is newer. I should look in your web site to learn what you think of the EF.



    Sam Hobbs
    SimpleSamples.Info
    Friday, December 23, 2011 8:47 PM
  • Hi Sam,

    I have looked at your web site and now I remember that you don't like things like TableAdapters but I think I did not realize that it is because of what you say here.

    That (tightly coupling DataSets to databases) and the fact that DataAccess classes should be a totally separate layer in their own projects (DLLs), not in the UI projects.

    As for the part that you quoted, I am saying that if I bind the table to a second form and then update the data in the second form then the first form is not automatically updated with the new data. So if TableAdapters were designed to exists separately from a specific form then it would be easier to use one TableAdapter in multiple forms

    Why requery the database at all? I guess it does really depend on your forms functionality, but one thing you could do is pass DataSets between forms. Take a look at this blog post:

    http://geek-goddess-bonnie.blogspot.com/2011/01/passing-data-between-forms.html

    Oh, so perhaps that is a clue; it is possible to create an instance of a TableAdapter that does not exist in a form. I will try something like that.

    Yes, if you leave them in the generated DataSet and have the DataSets in their own separate projects ... but that doesn't do away with the fact that the DataSet is still tightly-coupled to the database. You probably already read my blog post about this:

    http://geek-goddess-bonnie.blogspot.com/2009/09/tableadapters-are-c-r-a-p.html  (remove the "-" from the word c-r-a-p ... I've had this get censored in the past if spell the word.)  There's an updated link at the end of the blog post that refers to a newer post about how to create an XSD without having all the TableAdapter stuff put in there).

    And there's also the three-part series on DataAccess (you should be able to find those just above the TableAdapter post ... the Part I in September and Parts II and III in October).

    I know that TableAdapters are older technology and that the Entity Framework is newer. I should look in your web site to learn what you think of the EF.

    You won't find any EF references on my blog. I haven't had the time to play around with it, since DataSets have worked just fine for me for a long time. One of these days I suppose I should take a look, but I've been too busy so far.

     


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Friday, December 23, 2011 9:13 PM
  • Thank you, I will look at those too.

     

    Why requery the database at all?

    That is the point I was making. I was saying that if I do it one way then we must requrey but if we do it the way I am asking then we do not need to. You however would not do it either way so that makes this irrelevant.

     



    Sam Hobbs
    SimpleSamples.Info
    Friday, December 23, 2011 11:12 PM
  • Well, let us know what you decide to do after reading my blog posts. If you do not want to refactor stuff (or don't refactor all, just some) and still have questions ... then fire away! =0)
    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Saturday, December 24, 2011 2:20 AM
  • Thank you. I will let you know when I have something worthwhile. That might be a while; I have other priorities.

    Sam Hobbs
    SimpleSamples.Info
    Tuesday, December 27, 2011 4:12 AM
  • Hi Simple Samples,

    Have you solved the issue? I look forward to hearing from you.

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us
    Monday, January 2, 2012 2:13 AM
    Moderator
  • Thank you, Allen.

    No, I have not found a solution. The thing is that I am nearly certain that I have found a solution in the past and if so then it is not obvious. It is hidden someplace I do not expect it to be. So I need to hunt through my previous code to find the solution. I have given this a lower priority for now. I will share what I find if I find it. It might be hidden someplace such as in the BindingSource.

    I really think that TableAdapters need to be documented better. They are different in the sense of existing only as generated code, but they could be documented somehow. Visual Studio has a mature method of putting documentation in code but TableAdapters do not use it. That is adequate proof to me of a significant deficiency that does not need to exist.



    Sam Hobbs
    SimpleSamples.Info
    Monday, January 2, 2012 3:34 AM
  • Sam,

    The easiest way to address your problem is to pass objects between your two forms, the form that displays the grid of all your data rows (MasterForm) and the form for editing rows (EditForm).

    You can continue to use the TableAdapter that you have dragged onto your MasterForm ... but don't drag a second TableAdapter to your EditForm. Pass your DataSet(or DataTable or DataRow) to your EditForm (and if you want to update the database from the EditForm rather than from the MainForm, you can pass your TableAdapter too).

    Because you've passed the data object from the MainForm to the EditForm, when data is updated on the EditForm, you will see it gets updated on the MainForm automatically. This has nothing to do with whether you save it to the database or not. It has to do with the fact that the data on EditForm is the same object as the data on MainForm.

    Does this help?


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Monday, January 2, 2012 4:37 PM
  • Hi Simple Samples,

    I can see there has been a lot of work done already on this so forgive me if I'm on the wrong track.

    To automatically have default values set in a newly created row edit each column in your Typed dataset to set a default value as in the screen grab.

    That way you shouldn't have to programmatically set each value.

    That may also help with your other follow-up issues.

    Chris

    Monday, June 11, 2012 2:41 PM
  • If I ignore the errors and continue, then later I get the error that a field does not allow nulls. 

    Sam,

    I hope you don't mean with ignore the error put something around that like this.

    VB

    Try
    'do methods
    Catch
    'ignore errors
    End Try

    C#
    try {//do methods}catch{//}

    if you are doing this more then your problem can be nobody will ever know.



    Success
    Cor

    Tuesday, June 12, 2012 4:49 AM
  • Thank you, Chris.

    First let me say that if I had known this was going to be this big of an issue then I would not have created this thread.

    My question would likely be easily answered by looking at the documentation but TableAdapters are not documented. The answer I am looking for is specific to TableAdapters. Setting a default value different from the default default value is irrelevant. In other words, a number field is initialized to zero by default, unless the field allows nulls. You need to understand that in order to understand my question.

    It is normal behavior to initialize a number field to zero by default unless the field allows nulls. My problem is that the record is not being created. I feel like pulling my hair out because I just don't understand why the problem is not understood. The problem is very clear to me. Okay, so in my original question I say "I need for the row to be created with default values only". When I say default values, zero is the default default value for numbers. For the purposes of this question, I do not need to use any other value for the default value for numbers.

    There are no follow-up issues.



    Sam Hobbs
    SimpleSamples.Info

    Tuesday, June 12, 2012 5:52 AM
  • Cor, please ignore the comment "If I ignore the errors and continue". That is not relevant to the problem; it is relevant to Bonnie's reply.

    The answer is specific to TableAdapters; the problem is not solved using language features such as try/catch blocks.



    Sam Hobbs
    SimpleSamples.Info

    Tuesday, June 12, 2012 5:57 AM
  • Cor, please ignore the comment "If I ignore the errors and continue". That is not relevant to the problem; it is relevant to Bonnie's reply.

    The answer is specific to TableAdapters; the problem is not solved using language features such as try/catch blocks.



    Sam Hobbs
    SimpleSamples.Info

    No but the problem can occur because of using language features wrong.

    You have the problem, which those who use it correct (and that are millions), don't 

    In an analogy you write: I dive in Australia in a sea full of big sharks, if I ignore those I don't reach the point which I want to reach; what is the problem?

    Simply don't ignore the sharks but try to find a solution for that. Be aware that it can be a shark you have ignored in a previous state in another not handled try and catch block.

    Be aware these forums are not only meant for single persons but also for those searching for answer on problems. I assume you are not interested in my replies, but those should not been set in a wrong direction.


    Success
    Cor



    Tuesday, June 12, 2012 12:00 PM
  • No Cor; you simply do not understand the problem. I probably should not reply to your comments, but I don't want to mislead others in the wrong direction.

    I am interested in your help with the problem. You are assuming that I misunderstand and therefore you are trying to explain what you you think I misunderstand but instead you should try to understand.

    To continue with the Sharks analogy, I am swimming in a fresh-water lake and your are telling me to watch out for Sharks.



    Sam Hobbs
    SimpleSamples.Info

    Tuesday, June 12, 2012 4:43 PM
  • Hi Sam,

    This is an old thread. I guess you never solved your problems. What's the current architecture of your project? Did you refactor it at all? Did you use any of my suggestions?


    ~~Bonnie Berent DeWitt [C# MVP]

    geek-goddess-bonnie.blogspot.com

    Thursday, June 14, 2012 3:47 PM
  • Thank you for your concern, Bonnie.

    The priority of this is low. I have not gotten back to it. I want to.

    I do not know what refactor means. I assume you are referring to separation of data and UI. That should be done in systems to be developed and/or maintained by multiple developers during the life of the software. For this situation, the solution I attempted to develop would be an improvement compared to what was otherwise proposed.



    Sam Hobbs
    SimpleSamples.Info

    Thursday, June 14, 2012 4:53 PM