Hi,

Any advice please.

I have various forms (e.g. frmCustomers, frmProducts), each having bindingSources and tableAdapters. The forms have the required Fill methods triggered from their constructors. It appears that the DataTable filled only exists in the App for as long as the form does.

What I want is a method to have the DataTable that has been filles, stay in scope within the app so I can use it again without having to call Fill again.

Anybody have a good way of doing this? Maybe copy the DataTables to local variables in the Parent form?

Cheers.

Recommended Answers

All 11 Replies

Hello.
If I understood you correctly - this may be helpful for you: Implementing Singleton in C#

Hi, Antenka.

No, that isn't what I meant. I am after a good way / technique to persist the datatable's data populated by tabeadapters on particular forms. If form closes the app can't use that datatable/data anymore. I am making copies into a static class for now but wanted to know if there are any other ways.

Well, the other way could be storing datatable/data in your main form. And pass them to other forms of your application at creation time.

You can save the dataset schema (structure) along with table data. This uses a dynamically created DataSet/DataTable but it will work for typed datasets as well.

Creating, Populating, and persisting the dataset:

private void button1_Click(object sender, EventArgs e)
    {
      DataSet ds = new DataSet();
      ds.EnforceConstraints = true; //enforce locally since there is no remote db server

      #region setup beer table in a limited scope
      {
        DataTable dtBeer = new DataTable();
        dtBeer.TableName = "Beer"; //Very important to set the table name when serializing datatables
        dtBeer.Columns.Add(new DataColumn("Brand", typeof(string)));
        dtBeer.Columns.Add(new DataColumn("SOH", typeof(int))); //"SOH" - Stock on hand
        dtBeer.Columns.Add(new DataColumn("OrderQty", typeof(int))); //amt to pick up next time you're at the store. This could make your list :)
        dtBeer.Columns["Brand"].Unique = true;

        DataRow row = dtBeer.NewRow();
        row["Brand"] = "Bud Light";
        row["SOH"] = 5;
        row["OrderQty"] = 0;
        dtBeer.Rows.Add(row);

        row = dtBeer.NewRow();
        //This stuff is $8 for 4 bottles at my local store. I'm sure you can get it much
        //cheaper as it is a belgian beer, a lot closer to you!
        row["Brand"] = "Allagash White"; 
        row["SOH"] = 8;
        row["OrderQty"] = int.MaxValue;
        dtBeer.Rows.Add(row);

        ds.Tables.Add(dtBeer);
      }
      #endregion

      #region setup wine
      {
        DataTable dtWine = new DataTable();
        dtWine.TableName = "Wine"; 
        dtWine.Columns.Add(new DataColumn("Brand", typeof(string)));
        dtWine.Columns.Add(new DataColumn("SOH", typeof(int))); 
        dtWine.Columns.Add(new DataColumn("OrderQty", typeof(int)));
        dtWine.Columns.Add(new DataColumn("Location", typeof(string)));
        dtWine.Columns["Brand"].Unique = true;

        DataRow row = dtWine.NewRow();
        row["Brand"] = "Wine1"; //i'm a beer guy
        row["SOH"] = 5;
        row["OrderQty"] = 0;
        row["Location"] = "Basement Cellar, Rack #1, Third row from the bottom";
        dtWine.Rows.Add(row);

        row = dtWine.NewRow();
        row["Brand"] = "Win2";
        row["SOH"] = 8;
        row["OrderQty"] = 0;
        row["Location"] = "Attic collection, on top of the exhaust fan";
        dtWine.Rows.Add(row);

        ds.Tables.Add(dtWine);
      }
      #endregion

      #region save the dataset to disk
      ds.WriteXml(@"C:\database.xml", XmlWriteMode.WriteSchema); //You have to write the schema or it will fail when loading
      #endregion
    }

Loading the dataset from disk:

private void button2_Click(object sender, EventArgs e)
    {
      DataSet ds = new DataSet();
      ds.ReadXml(@"C:\database.xml", XmlReadMode.Auto);
      int beerCount = ds.Tables["Beer"].Rows.Count;
      int wineCount = ds.Tables["Wine"].Rows.Count;
      System.Diagnostics.Debugger.Break();
    }
commented: LOL! :) +5

Hi, Sknake.

I think that would be a bit too much code for what I need. I just need to save a number of datatables (about 6) data in memory when they are created on seperate forms.

I think the way Antenka mentioned, placing references in the Main form is what I have done. Wondering really if there was a way / option for the data once loaded into the DataSet.xsd to persist?

That depends.

If the dataset is a typed dataset created on a form with the designer then when the form closes it will call dispose since the designer adds it to the controls/components for the form. If you're creating a dataset in code then as long as you hold on to a reference it won't be garbage collected.

You could also use the same code I posted to persist a byte[] array in memory and deserialize that data on another form.

>>I think that would be a bit too much code for what I need.
You do realize that 99% of that code was for creating the dataset and populating it, right? The code to persist and recreate the dataset is minimal:

Persist

ds.WriteXml(@"C:\database.xml", XmlWriteMode.WriteSchema); //You have to write the schema or it will fail when loading

Load from buffer:

DataSet ds = new DataSet();
      ds.ReadXml(@"C:\database.xml", XmlReadMode.Auto);

Hi, Sknake.

Yes, I see what you mean. Not sure if I like the idea of doing all the IO, never seen anybody in my team do that. Thinking RAM should be the way to go.

I guess the key question is, is there a way I can add a binding source and somehow the automatically generated tableadapter to a class, then I can manage the exsitance of this class (to persist the data)?

RAM doesn't persist your data. It only keeps it in memory.

You don't need a table adapter with this method. Instead of using a table adapter to populate the dataset you are deserializing it. They are two different approaches.

[edit]
I think you are confusing persisting a dataset (saving it to disk) versus sharing a dataset (between forms). Are you trying to have a single instance of a DataSet on multiple forms with multiple binding sources against the same data?
[/edit]

Persist in RAM ideally. e.g. I have a form for entering new customers / editing existing customers. I have another form that want to have a small listbox listing just the customer's firstnames and secondnames...Didn't want to have to place another bindingsource and tableadapter on this form. would be nice to have persisted the data (customers table in dataset) in memory. I can achieve this by copy it to a variable in a static class or main MDI parent form. was wondering if there are other ways in visual studios to accomplish this.

save it in RAM I meant! Yes, so other forms can use it.

Antenka already gave you the same solution I would recommend. Pass a reference of the dataset to other forms as they are created at runtime.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.