Click here to Skip to main content
15,889,462 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
On my form i have a textbox, 2 datagridviews (master-detail), and a search button

SelectCommand for Master DataAdapter has a parameter to limit retrieved rows.

select * from master_table where x_column = some_value

currently, my SelectCommand for Detail DataAdapter is :

select * from detail_table

when i tried to create a DataRelation between master and detail based on master's primary

key, i got an exception :

this constraint cannot be enabled as not all values have corresponding parent values.

i think it's because master rows are filtered by a parameter, while detail rows are not...

what should i do?



C#
public partial class Form1: Form
{
    private String connectionString = null;
    private OracleConnection oracleConnection = null;
    
    private String equQuery = null;
    OracleCommand equCmd = null;
    private OracleDataAdapter equDataAdapter = null;        
    private OracleCommandBuilder equComBldr = null;       
    private DataTable equDataTable = null;
    private BindingSource equBindingSource = null;
    
    private String partQuery = null;
    OracleCommand partCmd = null;
    private OracleDataAdapter partDataAdapter = null;
    private OracleCommandBuilder partComBldr = null;
    private DataTable partDataTable = null;
    private BindingSource partBindingSource = null;
    
    private DataSet dataset = null;
    
    
    
    private void Form1_Load(object sender, EventArgs e)
    {
    
        oracleConnection = new OracleConnection(connectionString);
        oracleConnection.Open();
        
        
        // SELECT COMMAND FOR MASTER TABLE
        equQuery = "select bill_equ_id  ,bill_id ,equ_serial_nbr ,equ_cost ,maintenance_date from bso_equipment_maint_bill_equ where bill_id = :bill_id";
        
        equCmd = new OracleCommand(equQuery, oracleConnection);
        equCmd.Parameters.Add("bill_id", OracleType.Number);

        /* initial value to make master grid retrieve no data on load */
        equCmd.Parameters["bill_id"].Value = -1;
        
        
        // SELECT COMMAND FOR DETAIL TABLE… !!!???????
        /* since command has not parameters, grid is being filled with ALL detail records on load.  i don't know how to get only rows related to retrieved master rows */
        
        partQuery = "select bill_equ_id , part_nbr , part_cost , quantity from bso_equipment_maint_bill_part ";            
        
        partCmd = new OracleCommand(partQuery, oracleConnection);
        
        
        
        // CREATE ADAPTERS
        equDataAdapter = new OracleDataAdapter(equCmd);
        equComBldr = new OracleCommandBuilder(equDataAdapter);
        
        
        partDataAdapter = new OracleDataAdapter(partCmd);
        partComBldr = new OracleCommandBuilder(partDataAdapter);
        
        
        // CREATE AND FILL DATA TABLES
        equDataTable = new DataTable();
        equDataTable.TableName = "bso_equipment_maint_bill_equ";
        partDataTable = new DataTable();
        partDataTable.TableName = "bso_equipment_maint_bill_part";
        
        equDataAdapter.Fill(equDataTable);
        partDataAdapter.Fill(partDataTable);
        
        /* bill_equ_id is a foreign key in details table. It is the primary key in master table. It’s generated on database by a (before-insert trigger) */
        
        partDataTable.Columns["bill_equ_id"].AutoIncrement = true;
        partDataTable.Columns["bill_equ_id"].AutoIncrementSeed = -1;
        partDataTable.Columns["bill_equ_id"].AutoIncrementStep = -1;
        
        // CREATE DATASET AND RELATION
        dataset = new DataSet();
        dataset.Tables.Add(equDataTable);
        dataset.Tables.Add(partDataTable);
        
        
        /* this line throws an exception : this constraint cannot be enabled as not all values have corresponding parent values */
        
        DataRelation relation = new DataRelation("EquPartRel", dataset.Tables["bso_equipment_maint_bill_equ"].Columns["bill_equ_id"], dataset.Tables["bso_equipment_maint_bill_part"].Columns["bill_equ_id"]);            
        dataset.Relations.Add(relation);
        
        
        // CREATE BINDING SOURCES AND BIND TO DATAGRIDVIEWS
        equBindingSource = new BindingSource();
        equBindingSource.DataSource = dataset;
        equBindingSource.DataMember = "bso_equipment_maint_bill_equ";
        equGrid.DataSource = equBindingSource;
        equGrid.Columns["bill_id"].Visible = false;
        equGrid.Columns["bill_equ_id"].Visible = false;
        
        partBindingSource = new BindingSource();
        partBindingSource.DataSource = dataset;
        partBindingSource.DataMember = "bso_equipment_maint_bill_part";
        partGrid.DataSource = partBindingSource;
        partGrid.Columns["bill_equ_id"].Visible = false;
        
        
        oracleConnection.Close();
        
    
    } // end of form load
    
    
    
    private void searchEquButton_Click(object sender, EventArgs e)
    {
    
        equDataAdapter.SelectCommand.Parameters["bill_id"].Value = bill_id;               
        
        equDataAdapter.Fill(equDataTable);
        partDataAdapter.Fill(partDataTable);            
    
    } // end search
    
} // class

data currently in master table :



bill_equ_id    bill_id     equ_serial_nbr  equ_cost   maintenance_date 
1                   1              1            1000      31/08/2014
8                   3              a-400        5000      30/08/2014



data currently in detail table :

C#
bill_equ_id       part_nbr      part_cost     quantity
1                  a-209         500             1
1                  a-210         800             2
8                  a-211         2500            2
Posted
Updated 8-Sep-14 22:30pm
v4
Comments
George Jonsson 8-Sep-14 8:41am    
This is really not not enough information.
1. You use SELCECT *, which hides all column information. (And it is bad coding standard)
2. You don't show the c# code where you assign the data tables and create the relation.

We cannot see your screen or guess your code.
nina4ever 9-Sep-14 2:29am    
okay, i just tried to make my question as simple as possible. i will provide more details soon. thank you for your concern.
George Jonsson 9-Sep-14 2:34am    
Well, think about the information you would need to answer the question.
nina4ever 9-Sep-14 4:30am    
update done :)
Anand Gunasekaran 8-Sep-14 14:24pm    
Sample i/p & o/p need!

1 solution

I am not sure but I think the problem might be your composite primary key in the detail table.


I tried this code and it works fine.
I used the data you provided in the question.

C#
DataTable dtMaster = new DataTable("bso_equipment_maint_bill_equ");

// I have to fill the tables manually
DataColumn dcMasterPK = dtMaster.Columns.Add("bill_equ_id", typeof(int));
dtMaster.PrimaryKey = new DataColumn[] { dcMasterPK };
dtMaster.Columns.Add("bill_id", typeof(int));
dtMaster.Columns.Add("equ_serial_nbr", typeof(string));
dtMaster.Columns.Add("equ_cost", typeof(decimal));
dtMaster.Columns.Add("maintenance_date", typeof(DateTime));

dtMaster.Rows.Add(1, 1, "1", 1000, DateTime.ParseExact("31/08/2014", "dd/MM/yyyy", null));
dtMaster.Rows.Add(8, 3, "a-400", 5000, DateTime.ParseExact("30/08/2014", "dd/MM/yyyy", null));

DataTable dtDetail = new DataTable("bso_equipment_maint_bill_part");

dtDetail.Columns.Add("bill_equ_id", typeof(int));
dtDetail.Columns.Add("part_nbr", typeof(string));
dtDetail.Columns.Add("part_cost", typeof(decimal));
dtDetail.Columns.Add("quantity", typeof(string));

dtDetail.Rows.Add(1, "a-209", 500, 1);
dtDetail.Rows.Add(1, "a-210", 800, 2);
dtDetail.Rows.Add(8, "a-211", 2500, 2);

DataSet ds = new DataSet();
ds.Tables.Add(dtMaster);
ds.Tables.Add(dtDetail);

DataRelation relation = new DataRelation("EquPartRel", ds.Tables["bso_equipment_maint_bill_equ"].Columns["bill_equ_id"], ds.Tables["bso_equipment_maint_bill_part"].Columns["bill_equ_id"]);
ds.Relations.Add(relation);

BindingSource bsMaster = new BindingSource(ds, "bso_equipment_maint_bill_equ");
BindingSource bsDetail = new BindingSource(bsMaster, "EquPartRel");

dgMaster.DataSource = bsMaster;
dgDetail.DataSource = bsDetail;


Maybe you should try to printout the contents of both tables before you create the relation.
 
Share this answer
 
v3
Comments
nina4ever 9-Sep-14 6:21am    
done. this line still gave exception :

DataRelation relation = new DataRelation("EquPartRel", dataset.Tables["bso_equipment_maint_bill_equ"].Columns["bill_equ_id"], dataset.Tables["bso_equipment_maint_bill_part"].Columns["bill_equ_id"]);
dataset.Relations.Add(relation);


I removed the where clause from master SelectCommand, and the exception disappeared, but when i ran the form:
master grid displayed all master table rows
detail grid displayed ALL detail table rows together, even when i click on a row from master grid, detail grid still display all rows, not only corresponding ones
George Jonsson 9-Sep-14 6:55am    
I updated the solution.
Please try again.
nina4ever 9-Sep-14 7:07am    
dear George, it gave an exception because relation columns (primary keys) are not the same length.
"ParentColumns and ChildColumns" should be the same length
George Jonsson 9-Sep-14 7:45am    
I think I led you on the wrong path.
See my updated answer.
nina4ever 9-Sep-14 8:00am    
give me a few minutes to test this and compare it to my code. thank you, sir

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900