ADO.NET, DataSet and pulling related data from the SQL 2k

Please let me know if at any point I'm trying to force my way through doors already open :)

My goal is to write a class that would enable me to populate the whole dataset with schemas of tables being in relation with the one in the basic SQL query and fill those tables with relevant data. Eg if I have table UserCoreInfo consisting of columns user_pk_id (identity, autoincrement) and user_name and another one UserContactInfo, consisting of some address details, own unique id and column contact_fk_user_id being a foreign key in many-to-one relation to the UserCoreInfo table, I'd like a query like "SELECT TOP 1 * FROM UserCoreInfo" to automaticaly create both related tables' schemas in the dataset, put in place the foreign key relation, then pull one row into UserContactInfo and all the related rows into UserContactInfo. I'm currently at the beginning stages of this stuff and have some questions about SqlDataAdapter. 

Once I've established the structure manually, like this:

SqlCommand sqlcommand_members = new SqlCommand("SELECT * FROM UserCoreInfo",sqlconnection_Internal);
sqldataadapter_Internal.SelectCommand = sqlcommand_members;
sqldataadapter_Internal.FillSchema (dataset_temp, System.Data.SchemaType.Mapped,"UserCoreInfo");

sqlcommand_members = new SqlCommand("SELECT * FROM UserContactInfo",sqlconnection_Internal);
sqldataadapter_Internal.SelectCommand = sqlcommand_members;
sqldataadapter_Internal.FillSchema (dataset_temp, System.Data.SchemaType.Mapped,"UserContactInfo");

DataColumn datacolumn_parent = dataset_temp.Tables["UserCoreInfo"].Columns["user_pk_id"];
DataColumn datacolumn_child = dataset_temp.Tables["UserContactInfo"].Columns["contact_fk_user_id"];
DataRelation datarelation_temp = new DataRelation("user_pk_id_||_contact_fk_user_id",datacolumn_parent,datacolumn_child,true);

dataset_temp.Relations.Add(datarelation_temp);

Can I do anything to fill both the relation-connected tables in the dataset_temp with the related data in one go, without the need for writing an sproc (I don't like those - make you unable to use any other db) or executing two separate SQL SELECT queries



Answer this question

ADO.NET, DataSet and pulling related data from the SQL 2k

  • -Eric Bouguen-

    Nah, doesn't all that much. I've fiddled a bit and actually found a way of writing a class that would take care of all those things automatically, both populating the dataset with relevant schemas and drawing the related data, but have now problems with display. I won't be using datagrid at all (it's bloody damned ugly and not very user-friendly and I consider it a classic case of a control written for programmers only ;> ), rather some related textboxes and comboboxes. And here I hit another problem:

    While relating to a child DataTable works perfectly well (the very same stuff you've described above), relating to the parent table doesn;t work at all or at least I haven't found any way of writing the navigation path accordingly. What I mean is this:

    1. You have a core table Table1. You have a secondary table Table2. You establish a relation Relation1 where primary key in Table1 is referenced by a foreign key in Table2. Then you can bind the controls by seting the DataSource to your DataSet and giving the navigation path as Table1.Relation1.Table2. Ok, works fine, the BindingContext for the form will affect (by changing the Position) all the forms. But:

    2. You have exactly the same situation, but the relation is reversed. Table1 has a foreign key pointing to Table2. Now navigation path:

    Table1.Relation1.Table2 

    will not work at all. In my case it was Table1 as a core table, Table2 related to it as a child table and than Table3 related to Table2 as a parent table. Thus Table2 had two parent tables - Table1 and Table3. As the core data is being drawn from Table1 what I need is an ability to create binding like this:

    Displaymember = "Table1.Relation1.Table2.Relation2.Table3";

    this will work if and only if Table2 is a child of table1 and table3 is a child of table2. Is it at all possible to navigate the relation "upstream"

    Sorry if I make anyone's head ache :)

  • Lauski

    You are going to have to fill each datatable (or at least the schema) and then manually create relations between them in your dataset and then fill them with data.

    THen you just set your databindings correctly, like if using a datagrid then set it to the first table and notice that each relation shows up under the plus sign or as you hit each plus sign. This is showing you that the datagrid shows you records based on the parent record selected, it will do this for each relate table.

    You can do this with other controls.

    You have to bind them correctly though.

    For example lets say you have a text box for the ID of the first parent table

    textbox1.databindings.add(new binding("Text",dataset1,"Datatable1.ColumnName"))

    Now you want to bind a second textbox to another table and show the record of the one currently related to the first textbox.

    textbox2.databindings.add(new binding("Text",dataset1,"Datatable1.Relation1.ColumnName"))

    You see how that went

    Now if you were doing different datagrids all over the form (one for each datatable) you would do this

    datagrid1.datasource = dataset (this would be the same for all datagrids)
    datagrid1.datamember = "Datatable1"
    datagrid2.datamember = "DataTable1.Releate1"

    Then for another relate within a relate
    datagrid3.datamember = "Datatable1.Relate1.Relate2"

    This would be something like
    Customer --->Orders---->OrderDetails

    Hope this helps. and remember you can find alot of information at

    http://www.syncfusion.com/FAQ/WinForms/default.asp#44

  • asics64

    Made my Head Ache LOL.

    Keep in mind when you do "Table1.releation1" that's like "Table1.table2", the relation is the table2. So to property do a third relation you would go "Table1.Relate1.Relate2" you see

    Now I can see a reverse working only if they are all 1 to 1 relations, if many to one, then I see problems.

    Does this help

  • SkiinBlue

    I wonder if you are having the issue because of the primary key setup.

    You could redo your keys, you delete the primary keys in the table and you could even add another column for a seperate ID. Then do the relation. 

    Though I don't know about that.

    I see your issue, I wonder if you would not be better to just move it manually.

    For example you have your list box with rows, when you change selection you would then filter a dataview with the child table. You would bind your controls to the dataview.

    Yea so on selectindex change you filter the child table via dataview. That should work nicely.

    Let me know

  • Zaka Khan

    I'll try to explain more clearly what I mean. Please do bear in mind, that this is totaly abstract.

    You have a table Users. This table has following columns:

    --------------
    Column1: user_pk_id being the identity and autoincrement column
    Column2: user_Name - obvious
    Column3: user_Surname

    and so on...

    ColumnN: user_fk_Roles - a foreign key, pointing to the table Roles 
    --------------


    Now for the second table, Roles

    --------------
    Column1: role_pk_id being the identity and autoincrement column
    Column2: role_Title
    --------------

    Now let's fill the table 2 with following entries:

    role_pk_id: / role_Title:
    1 / LUser
    2 / User
    3 / Girl User With Big Buffers
    4 / Superuser
    5 / Admin
    6 / Domain Admin


    This is a common enumeration, entries in table Users will have 1 for LUser and so on. Now let's say that I have those two tables in the DataSet, table Roles populated with the whole enumeration and the table Users having one row only. If I establish a relation like this:

    DataColumn datacolumn_parent = dataset_temp.Tables["Roles"].Columns["role_pk_id"];
    DataColumn datacolumn_child = dataset_temp.Tables["Users"].Columns["user_fk_Roles"];
    DataRelation datarelation_temp = new DataRelation("Users2Roles",datacolumn_parent,datacolumn_child,true);
    dataset_temp.Relations.Add(datarelation_temp);

    I have Users as a child table and Roles as a parent table. As this is, obviously, many-to-one relation the problems you've mentioned do indeed appear. What I'd like to see would be a possibility of writing something like this:

    listbox1.DataSource = dataset_temp;
    listbox1.DisplayMember = "Users.Users2Roles.role_Title";
    listbox1.ValueMember = "Users.Users2Roles.role_pk_id";

    This will not work as the relation is a "reverse" one, a child to parent. This will work great for parent to child, but I just need some trick to do it both ways :) Of course I know that in this case the obvious solution is to populate the listbox1 with the data from Roles directly and set the SelectedValue from the Users table, but I'm giving this only as an example - my forms are a bit more complicated. I hope I made myself clear, sorry for the polish english if this is not the case. So - is there any way of writing the navigation path so that relations child-to-parent are navigated  Or providing it as a path like DataTable.ParentRelations["name"].ParentTable and so on


  • ADO.NET, DataSet and pulling related data from the SQL 2k