Well thats my problem. I'm trying to query a remote postgresql DB and then fill TWO RELATED instanced tables with the result, so i can fill a form that displays information for both tables. Doing this with a single table was simple, but now i'm unable to correctly define relationships. I'm getting the “Object reference not set to an instance of an object” error What im doing wrong?
Relation is "components/provider_id" to "provider/id" so i can fill provider fields automatically in the components forms (while doing a search query).
Heres my code:
OdbcDataAdapter sdata = new OdbcDataAdapter(//Query string whatever);
OdbcDataAdapter sdata2 = new OdbcDataAdapter(//Query string whatever);
DataSet ds = new DataSet(); //new dataset instance
DataTable dtbl = new DataTable(); //two new instanced tables
DataTable dtbl2 = new DataTable();
sdata.Fill(dtbl); //fill both tables with each query data
sdata2.Fill(dtbl2);
ds.Tables.Add(dtbl); //Add those tables to DataSet
ds.Tables.Add(dtbl2);
//So now im tring to create a relation between both tables
// im getting "“Object reference not set to an instance of an object”
DataRelation dr = new DataRelation("provcomp",
ds.Tables["dtbl"].Columns["id"],
ds.Tables["dtbl2"].Columns["id_prov_comp"]);
Also I suppose that after that i will need some advice on creating some keys for the columns.
Can I get a little help? Please keep in mind that im fairly new to programing in general and c# in particular.
You should add the relation to Relations collection of your DataSet:
DataSet ds = new DataSet(); //new dataset instance
DataTable dtbl = new DataTable("Your Parent TableName"); //two new instanced tables
DataTable dtbl2 = new DataTable("Your Child TableName");
sdata.Fill(dtbl); //fill both tables with each query data
sdata2.Fill(dtbl2);
ds.Tables.Add(dtbl); //Add those tables to DataSet
ds.Tables.Add(dtbl2);
ds.Relations.Add("Your Relation Name",dtbl.Columns["id"], dtbl2.Columns["id_prov_comp"]);
//or
//ds.Relations.Add(ds.Tables["dtbl"].Columns["id"], ds.Tables["dtbl2"].Columns["id_prov_comp"]);
ds.AcceptChanges();
Related
Greets! I am having problems importing a row I created into a DataTable that resides in a DataSet. I pre-populate the "newDataSet" from a SQL Database that is empty but it does contain Tables with a Schema already set up. I have verified that the DataTables in "newDataSet" are getting the Schema imported to them.
Everything looks right as there is no error logs, but no datarow is ever added. Both my Console.WriteLine report back the same Count.
Thank you for taking the time to review this. I appreciate you.
Initial Setup:
var DataSet newDataSet = new DataSet("foo"); // A SQL Adapater was used to fill this from a pre existing Database.
var checkDataSet = new DataSet();
var checkDataTable = new DataTable();
Cloning the DataSet and DataTable.
checkDataSet = newDataSet.Clone();
checkDataTable = checkDataSet.Tables["moreFoo"].Clone();
Creating the DataRow:
var newDataRow = checkDataTable.NewRow();
Filling the Columns in the DataRow:
newDataRow[0] = obj1;
newDataRow[1] = obj2;
newDataRow[2] = obj3;
Importing the DataRow to the "newDataSet" DataTable:
Console.WriteLine(newDataSet.Tables["moreFoo"].Rows.Count.ToString());
newDataSet.Tables["moreFoo"].ImportRow(newDataRow);
Console.WritelLine(newDataSet.Tables["moreFoo"].Rows.Count.ToString());
The answer is:
newDataSet.Tables["moreFoo"].ImportRow(newDataRow);
should be:
newDataSet.Tables["moreFoo"].Rows.Add(newDataRow.ItemArray);
I can't figure out why I am getting a "DataTable already belongs to another DataSet" exception.
Here is my code:
DataSet AlertSet = new DataSet();
DataTable generalAlertData = new DataTable("GeneralAlertData");
generalAlertData = //function that returns datatable
//throws exception
AlertSet.Tables.Add(generalAlertData)
When is another dataset being created and when is the generalAlertData datatable being added to it?
I tried using a slightly different syntax to create and add the table and got the same error:
DataSet AlertSet = new DataSet();
DataTable generalAlertData = //function that returns datatable
//throws exception
AlertSet .Tables.Add(generalAlertData);
It depends on what your function that retrieve the datatable does.
If that function use a DataAdapter and fills a dataset then you have the DataSet property of the table automatically assigned and you need to remove it before assigning a different DataSet
You could try this to remove the original DataSet and use your own
DataTable generalAlertData = GetTable();
DataSet u = generalAlertData.DataSet;
u.Tables.Remove(generalAlertData.TableName);
AlertSet.Tables.Add(generalAlertData);
So, if your hypothetical GetTable works in this way
public DataTable GetTable()
{
...
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
return ds.Tables[0];
}
then you have the DataSet assigned to the returned datatable.
Instead this code doesn't assign anything to the DataSet property
public DataTable GetTable()
{
...
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
The DataTable returned from the method call, was added to a DataSet. Make sure it's not added to a DataSet; just build a stand alone DataTable.
As a side-note, returning a DataTable from a method call that assigns to this one makes the line above it irrelevant (the new).
This is an old question now but maybe this answer will help others.
I too received this error. I looked through my source code, found literally no other datasets and was puzzled as to why this was happening.
The solution to my issue was in my data access library. It didn't have a "getDataTable" routine but I did have a getDataset routine. When I needed just a datatable I called getDataset and took the tables(0) datatable instance.
The end result of this is that I got back my datatable like I wanted, but the datatable was already part of the dataset returned from my data access call. Thus, the error.
I had to add a getDatatable routine into my data access library to eliminate this problem.
I had the same problem and I solved it using Remove. In my opinion, your code could be this:
DataSet AlertSet = new DataSet();
DataTable generalAlertData = new DataTable("GeneralAlertData");
AlertSet.Tables.Add(generalAlertData);
AlertSet.Tables.Remove(generalAlertData);
Please, let me know if this code works.
My working code was like this:
DataTable myTable = new DataTable();
private void Save()
{
DataSet myDataSet = new DataSet();
myDataSet.Tables.Add(myTable);
myDataSet.Tables.Remove(myTable);//This works
myDataSet.WriteXml("myTable.xml");
}
private void buttonSave_Click(object sender, EventArgs e)
{
Save();
}
Every time I clicked the button buttonSave, the message “DataTable already belongs to another DataSet" appeared. After writing the line code myDataSet.Tables.Remove(myTable);//This works the application started running without problems and now I can click the button more times, without losing the value of myTable and without the error message.
I hope this can help.
i have one dataset with 3 data tables again i have to add one more data table in same dataset at first position(Ex:mydataset.tables[0]th position) .can any one help me regarding this.
You will probably need to pull all the datatables out of the dataset into a list, get them in the right order, and then re-add them all to the dataset since you cannot insert to or modify the existing order:
var tables = new DataTable[4];
tables[0] = mynewtable;
tables[1] = mydataset.Tables[0];
tables[2] = mydataset.Tables[1];
tables[3] = mydataset.Tables[2];
mydataset.Tables.Clear();
mydataset.Tables.Add(Tables[0]);
mydataset.Tables.Add(Tables[1]);
mydataset.Tables.Add(Tables[2]);
mydataset.Tables.Add(Tables[3]);
I have MySQL database with four tables, and I've written form an example binding method. But this solution works well only with one table. If I bind more than one, dataGridViews will be filled with info, but Update and Delete commands work badly.
public void Bind(DataGridView dataGridView, string tableName)
{
string query = "SELECT * FROM " + tableName;
mySqlDataAdapter = new MySqlDataAdapter(query, conn);
mySqlCommandBuilder = new MySqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.UpdateCommand = mySqlCommandBuilder.GetUpdateCommand();
mySqlDataAdapter.DeleteCommand = mySqlCommandBuilder.GetDeleteCommand();
mySqlDataAdapter.InsertCommand = mySqlCommandBuilder.GetInsertCommand();
dataTable = new DataTable();
mySqlDataAdapter.Fill(dataTable);
bindingSource = new BindingSource();
bindingSource.DataSource = dataTable;
dataGridView.DataSource = bindingSource;
}
Should I use different mySqlDataAdapter or mySqlCommandBuilder for each new table? I've used different DataTable and BindingSource objects, but when I inserted new row in one table, I had an exception that I left empty field in other table. Any solutions or tips for this problem?
Thanks in advance!
Better late than never I guess...
I have an application that loads different tables into the same DataGridView using Visual Studio 2013. So far it is working!
1. DataTable
You certainly need to create a new one for each different table you want to load, otherwise you can not clear out the old data. You might think that
dataTable.Clear()
would do the trick but no, it leaves the old column headers behind so your new table is loaded to the right of all the old columns :-(. Although interestingly if your new table has a column with the same name as the old it merges them!
2. MySqlAdapter
I currently create a new one for each table, but at the very least your sql query is changing so you need to create a new SelectCommand:
MySqlCommand cmd = new MySqlCommand("SELECT * FROM `" + tableName + "`", conn);
sqlAdapter.SelectCommand = cmd;
I've tried this and it seems to work, but actually it is simpler to just create a new MySqlAdapter and performance really isn't an issue at this point!
3. SqlCommandBuilder
Yes you should create a new one because the update and delete commands will be different. I don't use a class variable but create one dynamically (i.e. as a local variable) when I need it.
4. BindingSource
I don't believe you need a new BindingSource, but I haven't used them very much so can't be certain.
How do you take a couple of data tables and put them in a dataset and relate (that doesn't even sound like correct English) them?
I know how to create datatables.
Here is an example from one of my classes
// create the relationship between Booking and Booking_MNI
DataRelation relBookingMNI;
relBookingMNI = new DataRelation("BookingToBookingMNI",dsBooking.Tables["Booking"].Columns["Record_Id"],dsBooking.Tables["Booking_MNI"].Columns["booking_record_id"]);
dsBooking.Relations.Add(relBookingMNI);
dsBooking is my main dataset that contains 2 tables Booking and Booking_MNI
Where the Record_Id is the primary key and booking_record_id is the foreign key
I changed the code below to match my first example. But I think this is what you are looking for. In our production code this will produce the plus "+" symbol to the left of the row which would allow you to drill into the related table. Again I took production code and made it look like the first example so I don't know if it will compile but it should get you going in the right direction.
DataTable dtBooking = ds.Tables[0];
DataTable dtBooking_MNI = ds.Tables[1];
dtBooking.PrimaryKey = new DataColumn[] {dtBooking.Columns["Record_Id"]};
dtBooking_MNI.PrimaryKey = new DataColumn[] {dtBooking_MNI.Columns["booking_Record_Id"]};
/* Setup DataRelation between the DataTables */
DataColumn[] dcBookingColsArray = new DataColumn[1] {dtBooking.Columns["Record_Id"]};
DataColumn[] dcBookingMNIColsArray = new DataColumn[1] {dtBooking_MNI.Columns["booking_record_Id"]};
DataRelation relBooking_To_MNI = new DataRelation("Booking_To_MNI",dcBookingColsArray,dcBookingMNIColsArray);
ds.Relations.Add(relBooking_To_MNI_Units);
// grid where you want to display the relationship
grdBooking.DataSource = ds;
Look at the DataRelation class. It is what is used in a DataSet to relate two DataTables together.
Let's say you've got your DataTables named "orders" and "orderDetails". You want to create a relationship between them by their OrderNumber columns. We'll assume that orders is the parent and orderDetails is the child. We want to loop through the orders and then print each one's related sub-totals.
DataSet orderData = new DataSet("OrderData");
orderData.Tables.Add(orders);
orderData.Tables.Add(orderDetails);
orderData.Relations.Add("Order_OrderDetails", orders.Columns["OrderNumber"], orderDetails.Columns["OrderNumber"]);
Now, when you want to use that relationship somewhere else in your code:
DataRelation orderRelation = orderData.Relations["Order_OrderDetails"];
foreach (DataRow order in orders.Rows)
{
Console.WriteLine("Subtotals for Order {0}:", order["OrderNumber"]);
foreach (DataRow orderDetail in order.GetChildRows(orderRelation))
{
Console.WriteLine("Order Line {0}: {1}", orderDetail["OrderLineNumber"], string.Format("{0:C}", orderDetail["Price"]));
}
}
try this here is two table 1. categories & 2. Products
string query = "SELECT * FROM Categories; SELECT * FROM Products";
SqlConnection con = new SqlConnection();
SqlDataAdapter da = new SqlDataAdapter(query,con);
DataSet ds = new DataSet();
da.Fill(ds, "CategoriesAndProducts"); //CategoriesAndProducts dataset
string s = ds.Tables[0].Rows[0]["Name"].ToString();
string s1 = ds.Tables[1].Rows[0]["Name"].ToString();
Console.WriteLine(s); //from categories [0][0] like Electronic
Console.WriteLine(s1); //from Products [0][0] like LG
Have you looked into LINQ?
http://msdn.microsoft.com/en-us/netframework/aa904594.aspx
Perhaps you're looking for an orm solution like Entity Framework, NHibernate or Linq to SQL?
Appologies if I've misunderstood the question.
If you use Visual Studio 2005 or later try the following:
Right-click your project and select "Add/NewItem...", then choose DataSet from the wizard, which will create you some xsd and open the dataset designer.
Now you can create multiple tables, add columns to each table and draw relations (foreign key, with/without cascading...) between those tables.
in the autogenerated [YourNewDataSet}.Designer.cs-file, you will find the source code for these relations.
Something like this:
this.relationFK_DataTable2_DataTable1 = new global::System.Data.DataRelation("FK_DataTable2_DataTable1", new global::System.Data.DataColumn[] {
this.tableDataTable2.asdfasColumn}, new global::System.Data.DataColumn[] {
this.tableDataTable1.asdfaColumn}, false);
As always you can strip quite some portion of this code, if you code by hand instead of using the designer.
private void CreateRelation()
{
// Get the DataColumn objects from two DataTable objects
// in a DataSet. Code to get the DataSet not shown here.
DataColumn parentColumn =
DataSet1.Tables["Customers"].Columns["CustID"];
DataColumn childColumn =
DataSet1.Tables["Orders"].Columns["CustID"];
// Create DataRelation.
DataRelation relCustOrder;
relCustOrder = new DataRelation("CustomersOrders",
parentColumn, childColumn);
// Add the relation to the DataSet.
DataSet1.Relations.Add(relCustOrder);
}