How to update dataset with multiple tables?

A

afunguy

I create 2 tables, ParentTable and ChildTable. The row in ChildTable
is referenced to ParentTable. But after updated and saved to
database, the row in ChildTable doesn't refer to the correct row in
ParentTable. You can see the following example to get the problems.
Is there any good way to update multiple tables by using
SqlDataAdapter.Update()? Thank you


/* New Rows in ParentTable and ChildTable
*
* ------ParentTable------
* ID Animal
* 1 Cat
*
*
* ------ChildTable------
* ID NAME ParentID
* "1 small cat 1"
*/


/*
* But after the new rows saved back to the database, the new rows
saved wrongly as:
*
* ------ChildTable------
* ID NAME ParentID
* 1 small bird 1
* 2 small dog 2
* 3 small cat 1 =====> The ParentID doesn't dynamically
change to 3 but keep the same as 1.
* This makes it doen't reference to
the correct row in ParentTable
*/


------------------------------------------------------------------------------------
I try to use 2 different ways to update tables. But they both result
in the same problem. The first way I use is to follow the update
sequence recommended by book:

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);

adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.ModifiedCurrent));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Added));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.ModifiedCurrent));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Added));

-------------------------------------------------------------------------------------
The 2nd way is to use 2 SqlDataAdapter seperately to update tables,
but still get the same problem : The Child table row "3 small cat 1"
is wrong

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);
adapter1.Update(NewDataSet.Tables["ChildTable"]);
adapter2.Update(NewDataSet.Tables["ParentTable"]);


Please refer to the UpdateTableMethod1() and UpdateTableMethod2() in
the codes I provide.

------------------------------------------------------------------------------------
I just put some codes on the website. If you are also interested, you
can just copy-paste the code on your file and run it. This code
would generate 2 tables and insert content to the tables in
NorthWindCs database in MsSql server. Please change the connection
string to yours.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace UpdateMultipleTables
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.DataGrid dataGrid1;
//private conStr = "Server=Local; SSPT = true; ";
private string conStr = "server=Local;User ID=sa;
PWD=hello;database=NorthWindCs";
SqlDataAdapter adapter1 ;
SqlConnection con ;
private DataSet NewDataSet;


public Form1()
{
InitializeComponent();
//Create the connection to DataBase
CreateConnection();
//Create tables "ParentTable" and "ChildTable". And Insert content
to the 2 tables
CreateDB();
//Create a new row in both ParentTable and ChildTable
CreateNewRow();

//I try 2 ways to update the tables. But both of them gave me the
same problem,
//The new row in "ChildTable": is WRONG!

//UpdateTable1Method1();
UpdateTableMethod2();
}


public void CreateConnection()
{
con = new SqlConnection(conStr);

}
//Create tables "ParentTable" and "ChildTable". And Insert content to
the 2 tables
public void CreateDB()
{
string commandText =
"if exists (select * from NorthwindCS.dbo.sysobjects where name
like 'ParentTable') "+
"Begin " +
"DROP TABLE ParentTable "+
"CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal
VARCHAR(40) NOT NULL ) "+
"INSERT INTO ParentTable( Animal) values('Bird') "+
"INSERT INTO ParentTable( Animal) values('Dog') "+
"END "+
"ELSE "+
"Begin "+
"CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal
VARCHAR(40) NOT NULL ) "+
"INSERT INTO ParentTable( Animal) values('Bird') "+
"INSERT INTO ParentTable( Animal) values('Dog') "+
"END "+

"IF exists (select * from NorthwindCS.dbo.sysobjects where name
like 'ChildTable') "+
"Begin "+
"DROP table ChildTable "+
"CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name
VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+
"INSERT INTO ChildTable( Name, ParentID) values('small bird', 1)
"+
"INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2)
"+
"END "+
"ELSE "+
"BEGIN "+
"CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name
VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+
"INSERT INTO ChildTable( Name, ParentID) values('small bird', 1)
"+
"INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2)
"+
"END ";


adapter1 = new SqlDataAdapter(commandText, con);

try
{


DataSet ds = new DataSet();
adapter1.Fill(ds);
dataGrid1.DataSource = ds;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}


}



/* New Rows in ParentTable and ChildTable
*
* ------ParentTable------
* ID Animal
* 1 Cat
*
*
* ------ChildTable------
* ID NAME ParentID
* "1 small cat 1"
*/


/*
* But after the new rows saved back to the database, the new rows
saved wrongly as:
*
* ------ChildTable------
* ID NAME ParentID
* 1 small bird 1
* 2 small dog 2
* 3 small cat 1 =====> The ParentID doesn't dynamically
change to 3 but keep the same as 1.
* This makes it doen't reference to
the correct row in ParentTable
*/

//Create a new row in both ParentTable and ChildTable
public void CreateNewRow()
{

//carete data in parent table
NewDataSet = new DataSet("NewDataSet");
DataTable ParentTable = new DataTable("ParentTable");
DataColumn dc = new DataColumn("ID", typeof(int));
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
ParentTable.Columns.Add(dc);
dc = new DataColumn("Animal", typeof(string));
ParentTable.Columns.Add(dc);
NewDataSet.Tables.Add(ParentTable);

DataTable ChildTable = new DataTable("ChildTable");
dc = new DataColumn("ID", typeof(int));
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
ChildTable.Columns.Add(dc);
dc = new DataColumn("Name", typeof(string));
ChildTable.Columns.Add(dc);
dc = new DataColumn("ParentID", typeof(int));
ChildTable.Columns.Add(dc);
NewDataSet.Tables.Add(ChildTable);

// DataRelation relation = new DataRelation("ParentChildRelation"
, ParentTable.Columns["ID"], ChildTable.Columns["ParentID"], true);
// NewDataSet.Relations.Add(relation);

DataRow dr = NewDataSet.Tables["ParentTable"].NewRow();
dr["Animal"] = "Cat";
NewDataSet.Tables["ParentTable"].Rows.Add(dr);

//carete data in child table
dr = NewDataSet.Tables["ChildTable"].NewRow();
dr["Name"] = "small cat";
dr["ParentID"] = NewDataSet.Tables["ParentTable"].Rows[0]["ID"];
NewDataSet.Tables["ChildTable"].Rows.Add(dr);
dataGrid1.DataSource = NewDataSet;


}

//This update method followed by the recommended sequence of
updateing tables in Oreilly book. But it doesn't solve
//my proble. The Child table row "3 small cat 1" is wrong
public void UpdateTableMethod1()
{
try
{

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);

adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.ModifiedCurrent));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Added));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.ModifiedCurrent));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Added));

}
catch(Exception e)
{
Console.WriteLine(e.Message);
}

}


//I try to use 2 SqlDataAdapter to update tables, but still get the
same problem : The Child table row "3 small cat 1" is wrong
public void UpdateTableMethod2()
{
try
{

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);
adapter1.Update(NewDataSet.Tables["ChildTable"]);
adapter2.Update(NewDataSet.Tables["ParentTable"]);

}
catch(Exception e)
{
Console.WriteLine(e.Message);
}

}


/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGrid1 = new System.Windows.Forms.DataGrid();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
this.SuspendLayout();
//
// dataGrid1
//
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor =
System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(16, 24);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(496, 216);
this.dataGrid1.TabIndex = 0;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(560, 294);
this.Controls.Add(this.dataGrid1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}

*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
S

Sahil Malik

You have to go through the tables recursively starting from child moving to
parent and then refresh the changes back to the dataset from the database
using a combination of the Merge command and Sqldataadapter.

David Sceppa's book - Pages #493 to 503 explain this really well.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik


afunguy said:
I create 2 tables, ParentTable and ChildTable. The row in ChildTable
is referenced to ParentTable. But after updated and saved to
database, the row in ChildTable doesn't refer to the correct row in
ParentTable. You can see the following example to get the problems.
Is there any good way to update multiple tables by using
SqlDataAdapter.Update()? Thank you


/* New Rows in ParentTable and ChildTable
*
* ------ParentTable------
* ID Animal
* 1 Cat
*
*
* ------ChildTable------
* ID NAME ParentID
* "1 small cat 1"
*/


/*
* But after the new rows saved back to the database, the new rows
saved wrongly as:
*
* ------ChildTable------
* ID NAME ParentID
* 1 small bird 1
* 2 small dog 2
* 3 small cat 1 =====> The ParentID doesn't dynamically
change to 3 but keep the same as 1.
* This makes it doen't reference to
the correct row in ParentTable
*/


------------------------------------------------------------------------------------
I try to use 2 different ways to update tables. But they both result
in the same problem. The first way I use is to follow the update
sequence recommended by book:

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);

adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.ModifiedCurrent));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Added));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.ModifiedCurrent));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Added));

-------------------------------------------------------------------------------------
The 2nd way is to use 2 SqlDataAdapter seperately to update tables,
but still get the same problem : The Child table row "3 small cat 1"
is wrong

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);
adapter1.Update(NewDataSet.Tables["ChildTable"]);
adapter2.Update(NewDataSet.Tables["ParentTable"]);


Please refer to the UpdateTableMethod1() and UpdateTableMethod2() in
the codes I provide.

------------------------------------------------------------------------------------
I just put some codes on the website. If you are also interested, you
can just copy-paste the code on your file and run it. This code
would generate 2 tables and insert content to the tables in
NorthWindCs database in MsSql server. Please change the connection
string to yours.



using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace UpdateMultipleTables
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.DataGrid dataGrid1;
//private conStr = "Server=Local; SSPT = true; ";
private string conStr = "server=Local;User ID=sa;
PWD=hello;database=NorthWindCs";
SqlDataAdapter adapter1 ;
SqlConnection con ;
private DataSet NewDataSet;


public Form1()
{
InitializeComponent();
//Create the connection to DataBase
CreateConnection();
//Create tables "ParentTable" and "ChildTable". And Insert content
to the 2 tables
CreateDB();
//Create a new row in both ParentTable and ChildTable
CreateNewRow();

//I try 2 ways to update the tables. But both of them gave me the
same problem,
//The new row in "ChildTable": is WRONG!

//UpdateTable1Method1();
UpdateTableMethod2();
}


public void CreateConnection()
{
con = new SqlConnection(conStr);

}
//Create tables "ParentTable" and "ChildTable". And Insert content to
the 2 tables
public void CreateDB()
{
string commandText =
"if exists (select * from NorthwindCS.dbo.sysobjects where name
like 'ParentTable') "+
"Begin " +
"DROP TABLE ParentTable "+
"CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal
VARCHAR(40) NOT NULL ) "+
"INSERT INTO ParentTable( Animal) values('Bird') "+
"INSERT INTO ParentTable( Animal) values('Dog') "+
"END "+
"ELSE "+
"Begin "+
"CREATE TABLE ParentTable( ID INT IDENTITY(1,1) NOT NULL , Animal
VARCHAR(40) NOT NULL ) "+
"INSERT INTO ParentTable( Animal) values('Bird') "+
"INSERT INTO ParentTable( Animal) values('Dog') "+
"END "+

"IF exists (select * from NorthwindCS.dbo.sysobjects where name
like 'ChildTable') "+
"Begin "+
"DROP table ChildTable "+
"CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name
VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+
"INSERT INTO ChildTable( Name, ParentID) values('small bird', 1)
"+
"INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2)
"+
"END "+
"ELSE "+
"BEGIN "+
"CREATE TABLE ChildTable( ID INT IDENTITY(1,1) NOT NULL , Name
VARCHAR(40) NOT NULL , ParentID INT Not NULL) "+
"INSERT INTO ChildTable( Name, ParentID) values('small bird', 1)
"+
"INSERT INTO ChildTable( Name ,ParentID) values('small dog', 2)
"+
"END ";


adapter1 = new SqlDataAdapter(commandText, con);

try
{


DataSet ds = new DataSet();
adapter1.Fill(ds);
dataGrid1.DataSource = ds;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}


}



/* New Rows in ParentTable and ChildTable
*
* ------ParentTable------
* ID Animal
* 1 Cat
*
*
* ------ChildTable------
* ID NAME ParentID
* "1 small cat 1"
*/


/*
* But after the new rows saved back to the database, the new rows
saved wrongly as:
*
* ------ChildTable------
* ID NAME ParentID
* 1 small bird 1
* 2 small dog 2
* 3 small cat 1 =====> The ParentID doesn't dynamically
change to 3 but keep the same as 1.
* This makes it doen't reference to
the correct row in ParentTable
*/

//Create a new row in both ParentTable and ChildTable
public void CreateNewRow()
{

//carete data in parent table
NewDataSet = new DataSet("NewDataSet");
DataTable ParentTable = new DataTable("ParentTable");
DataColumn dc = new DataColumn("ID", typeof(int));
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
ParentTable.Columns.Add(dc);
dc = new DataColumn("Animal", typeof(string));
ParentTable.Columns.Add(dc);
NewDataSet.Tables.Add(ParentTable);

DataTable ChildTable = new DataTable("ChildTable");
dc = new DataColumn("ID", typeof(int));
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dc.AutoIncrementStep = 1;
ChildTable.Columns.Add(dc);
dc = new DataColumn("Name", typeof(string));
ChildTable.Columns.Add(dc);
dc = new DataColumn("ParentID", typeof(int));
ChildTable.Columns.Add(dc);
NewDataSet.Tables.Add(ChildTable);

// DataRelation relation = new DataRelation("ParentChildRelation"
, ParentTable.Columns["ID"], ChildTable.Columns["ParentID"], true);
// NewDataSet.Relations.Add(relation);

DataRow dr = NewDataSet.Tables["ParentTable"].NewRow();
dr["Animal"] = "Cat";
NewDataSet.Tables["ParentTable"].Rows.Add(dr);

//carete data in child table
dr = NewDataSet.Tables["ChildTable"].NewRow();
dr["Name"] = "small cat";
dr["ParentID"] = NewDataSet.Tables["ParentTable"].Rows[0]["ID"];
NewDataSet.Tables["ChildTable"].Rows.Add(dr);
dataGrid1.DataSource = NewDataSet;


}

//This update method followed by the recommended sequence of
updateing tables in Oreilly book. But it doesn't solve
//my proble. The Child table row "3 small cat 1" is wrong
public void UpdateTableMethod1()
{
try
{

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);

adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Deleted));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.ModifiedCurrent));
adapter2.Update(NewDataSet.Tables["ParentTable"].Select(null,
null, DataViewRowState.Added));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.ModifiedCurrent));
adapter1.Update(NewDataSet.Tables["ChildTable"].Select(null, null,
DataViewRowState.Added));

}
catch(Exception e)
{
Console.WriteLine(e.Message);
}

}


//I try to use 2 SqlDataAdapter to update tables, but still get the
same problem : The Child table row "3 small cat 1" is wrong
public void UpdateTableMethod2()
{
try
{

adapter1= new SqlDataAdapter("Select * from ChildTable", con);
SqlDataAdapter adapter2= new SqlDataAdapter("Select * from
ParentTable", con);

SqlCommandBuilder sb = new SqlCommandBuilder(adapter1);
SqlCommandBuilder sb1 = new SqlCommandBuilder(adapter2);
adapter1.Update(NewDataSet.Tables["ChildTable"]);
adapter2.Update(NewDataSet.Tables["ParentTable"]);

}
catch(Exception e)
{
Console.WriteLine(e.Message);
}

}


/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGrid1 = new System.Windows.Forms.DataGrid();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
this.SuspendLayout();
//
// dataGrid1
//
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor =
System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(16, 24);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(496, 216);
this.dataGrid1.TabIndex = 0;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(560, 294);
this.Controls.Add(this.dataGrid1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}

*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top