Skip Navigation LinksHome > Articles > ADO.NET > How to handle identity column along with primary and foreign table using ADO.NET in C#

How to handle identity column along with primary and foreign table using ADO.NET in C#

It explains how we can use Dataset to handle the identity column in primary table along with foreign table.

By Pankaj   On   Tuesday, 30 September 2008

Page Views : 1384   |   Technologies : ADO.NET

Rating : Rated :
0
| More..
Download Source:

How to fetch, add, update and delete the records in primary table and foreign table when Primary key in the primary table is of identity type:

 

Introduction: In ADO.NET you can add, delete, update and/or fetch data table wise for more than one table using ado.net very easily. But if tables have relationship in between than referential integrity play very important rule during changing or creating the new records in the primary and foreign tables. In this article I would explain how you can create your business object, which has primary table with identity type of primary table and foreign table and maintain the referential integrity.

 

Dataset is a disconnected working replica of the database so identity type column becomes more difficult to manage at the code. In this article I would explain the how we can manage identity field in the relation tables.

 

In this article I have taken very simple tPrimary and tForeign tables. tPrimary has ID field as Identity and description similarly tForeign table contains ID and description. We have defined one to many relationship in between tPrimary and tForeign tables as shown in figure 1.


Figure 1

 

 

 

Here I have created the Entity Business object so that it becomes easy to understand the code. Its little complex process to understand, if you have any question, please let me know.

 

Let’s understand the few points here

  1. You have to write stored procedures for insert, update, and delete for each table.
  2. In the insert procedure of the primary table create out parameter of identity type columns so that ado.net can get the columns value after inserting the row and update the children rows accordingly.
  3. Create the data adapter for each table and create your own instance of the insert, update, and delete command.
  4. Need to define the Auto Increment Seed and Auto Increment Step property of the identity column in the table as -1.
  5. Need to fetch the Schema of the table.

 

Step 1: Code for the Primary Table:

 

_adpPrimary = new SqlDataAdapter(new SqlCommand("Select * from tPrimary where ID = " + _id, DBSourceConnection));

 

//Point 1 – Creating the insert command and attaching with insert stored procedure.

_adpPrimary.InsertCommand = new SqlCommand("sp_InsertPrimaryEntity", DBSourceConnection);

SqlCommand cmdInsert = _adpPrimary.InsertCommand;

cmdInsert.CommandType = CommandType.StoredProcedure;

 

cmdInsert.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

cmdInsert.Parameters["@ID"].Direction = ParameterDirection.Output;//point 2 creating the out paramter

cmdInsert.Parameters["@ID"].SourceColumn = "ID";

 

cmdInsert.Parameters.Add(new SqlParameter("@PDescription", SqlDbType.VarChar, 50));

cmdInsert.Parameters["@PDescription"].SourceColumn = "PDescription";

 

//Point 5: Fill the schema into the DataTable

_adpPrimary.FillSchema(_dsEntity, SchemaType.Source);

 

//rename the table name in the dataset

_dtPrimryEntity = _dsEntity.Tables["Table"];

_dtPrimryEntity.TableName = "tPrimary";

 

//if _ID is a vaild number then fetch the data from datbase.

if (_id > 0)

     _adpPrimary.Fill(_dsEntity, "tPrimary");

 

//Point 4: if ID is of identity type of column then set the auto increament seed //and step -1 so that it does not conflict with the exiting rows in the //database

_dtPrimryEntity.Columns["ID"].AutoIncrementSeed = -1;

_dtPrimryEntity.Columns["ID"].AutoIncrementStep = -1;

 

//Point 1: creating update command

_adpPrimary.UpdateCommand = new SqlCommand("sp_UpdatePrimaryEntity", DBSourceConnection);

SqlCommand cmdupdate = _adpPrimary.UpdateCommand;

cmdupdate.CommandType = CommandType.StoredProcedure;

 

cmdupdate.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

cmdupdate.Parameters["@ID"].SourceColumn = "ID";

 

cmdupdate.Parameters.Add(new SqlParameter("@PDescription", SqlDbType.VarChar, 50));

cmdupdate.Parameters["@PDescription"].SourceColumn = "PDescription";

 

//Point 1: creating Delete command

_adpPrimary.DeleteCommand = new SqlCommand("sp_DeletePrimaryEntity", DBSourceConnection);

SqlCommand cmdDelete = _adpPrimary.DeleteCommand;

cmdDelete.CommandType = CommandType.StoredProcedure;

 

cmdDelete.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

 

 

Similarly fetch and create the insert, update and delete command for the foreign table.

Step 2: Code for Foreign Table:

_adpForeign = new SqlDataAdapter(new SqlCommand("Select * from tForeign where ID = " + _id, DBSourceConnection));

_adpForeign.InsertCommand = new SqlCommand("sp_InsertForeignEntity", DBSourceConnection);

SqlCommand cmdForgienInsert = _adpForeign.InsertCommand;

cmdForgienInsert.CommandType = CommandType.StoredProcedure;

 

cmdForgienInsert.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

cmdForgienInsert.Parameters["@ID"].SourceColumn = "ID";

 

cmdForgienInsert.Parameters.Add(new SqlParameter("@SDescription", SqlDbType.VarChar, 50));

                    cmdForgienInsert.Parameters["@SDescription"].SourceColumn = "SDescription";

 

_adpForeign.FillSchema(_dsEntity, SchemaType.Source);

 

//rename the table name in the dataset

_dtForeignEntity = _dsEntity.Tables["Table"];

_dtForeignEntity.TableName = "tForeign";

 

//if _ID is a vaild number then fetch the data from datbase.

if (_id > 0)

    _adpForeign.Fill(_dsEntity, "tForeign");

 

_adpForeign.UpdateCommand = new SqlCommand("sp_UpdateForeignEntity", DBSourceConnection);

SqlCommand cmdForeignUpdate = _adpForeign.UpdateCommand;

cmdForeignUpdate.CommandType = CommandType.StoredProcedure;

 

cmdForeignUpdate.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

cmdForeignUpdate.Parameters["@ID"].SourceColumn = "ID";

 

cmdForeignUpdate.Parameters.Add(new SqlParameter("@SDescription", SqlDbType.VarChar, 50));

                    cmdForeignUpdate.Parameters["@SDescription"].SourceColumn = "SDescription";

 

_adpForeign.DeleteCommand = new SqlCommand("sp_DeleteForeignEntity", DBSourceConnection);

SqlCommand cmdForeignDelete = _adpForeign.DeleteCommand;

cmdForeignDelete.CommandType = CommandType.StoredProcedure;

 

cmdForeignDelete.Parameters.Add(new SqlParameter("@ID", SqlDbType.BigInt));

cmdForeignDelete.Parameters["@ID"].SourceColumn = "ID";

 

 

Step 3: Add the relation in bet the primary and foreign table

//set the relationship in between the primary and foreign data table

DataRelation rel = new DataRelation("PrimaryToForeign", _dtPrimryEntity.Columns["ID"], _dtForeignEntity.Columns["ID"]);

                    _dsEntity.Relations.Add(rel);

 

Step 4: Write a method to update changes into the database:

 

SqlTransaction trans = null;

try

{

    trans = _sqlConnection.BeginTransaction();

    _adpPrimary.InsertCommand.Transaction = trans;

    _adpPrimary.UpdateCommand.Transaction = trans;

    _adpPrimary.DeleteCommand.Transaction = trans;

 

    _adpForeign.InsertCommand.Transaction = trans;

    _adpForeign.UpdateCommand.Transaction = trans;

    _adpForeign.DeleteCommand.Transaction = trans;

 

 

    _adpPrimary.Update(_dsEntity, "tPrimary");

    _adpForeign.Update(_dsEntity, "tForeign");

 

    _dsEntity.AcceptChanges();

    trans.Commit();

}

catch (Exception ex)

{

    if (trans != null)

        trans.Rollback();

 

    System.Diagnostics.Trace.WriteLine(ex);

}

 

Step 5: To delete the data if required:

If you see in the above code I am calling update method first on primary table but in delete I have to do it in reverse. I am deleting all the records from the business object.

SqlTransaction trans = null;

 

 

 trans = _sqlConnection.BeginTransaction();

 _adpPrimary.InsertCommand.Transaction = trans;

 _adpPrimary.UpdateCommand.Transaction = trans;

 _adpPrimary.DeleteCommand.Transaction = trans;

 

 _adpForeign.InsertCommand.Transaction = trans;

 _adpForeign.UpdateCommand.Transaction = trans;

 _adpForeign.DeleteCommand.Transaction = trans;

 

 foreach (DataRow dr in _dtPrimryEntity.Rows)

 {

            DataRow[] chRows = dr.GetChildRows("PrimaryToForeign");

            foreach (DataRow drch in chRows)

            {

                drch.Delete();

            }

            dr.Delete();

        }

 

        //delete child rows first

        _adpForeign.Update(_dsEntity, "tForeign");

        _adpPrimary.Update(_dsEntity, "tPrimary");

        _dsEntity.AcceptChanges();

        trans.Commit();

}

catch (Exception ex)

{

    if (trans != null)

        trans.Rollback();

 

    System.Diagnostics.Trace.WriteLine(ex);

}

 

Now, from step 6 to step 9 we would see how to use the entity class in the code to fetch, update, delete and insert records.

 

Step 6: Code to fetch the data:

long id = Convert.ToInt64(txtID.Text);

SampleBOEntity boEntity = new SampleBOEntity(id);

System.Windows.MessageBox.Show("data for id = " + id.ToString() + " has been fetched successfully");

 

Step 7: Code to Add records:I am inserting 2 primary rows and its children rows and updating to the database.

 

SampleBOEntity boEntity = new SampleBOEntity(-1);

DataSet dsEntity = boEntity.EntityDataSet;

 

//adding First Relation Row

DataRow drParent = dsEntity.Tables["tPrimary"].NewRow();

drParent["PDescription"] = "Adding First Row";

DataRow drChild = dsEntity.Tables["tForeign"].NewRow();

 

drChild["SDescription"] = "Child of First Row";

drChild.SetParentRow(drParent);

 

dsEntity.Tables["tPrimary"].Rows.Add(drParent);

dsEntity.Tables["tForeign"].Rows.Add(drChild);

 

 

//adding Second Relation Row along with 2 foreign rows

DataRow drParent2 = dsEntity.Tables["tPrimary"].NewRow();

drParent2["PDescription"] = "Adding Second Row";

 

DataRow drChild2 = dsEntity.Tables["tForeign"].NewRow();

 

drChild2["SDescription"] = "Child of Second Row";

drChild2.SetParentRow(drParent2);

 

DataRow drChild3 = dsEntity.Tables["tForeign"].NewRow();

 

drChild3["SDescription"] = "Another Child of Second Row";

drChild3.SetParentRow(drParent2);

 

dsEntity.Tables["tPrimary"].Rows.Add(drParent2);

dsEntity.Tables["tForeign"].Rows.Add(drChild2);

dsEntity.Tables["tForeign"].Rows.Add(drChild3);

 

boEntity.SaveEntity();

System.Windows.MessageBox.Show("data saved to databse successfully");

 

 

Step 8: Code to fetch and make amendment in the rows:

 

long id = Convert.ToInt64(txtID.Text);

SampleBOEntity boEntity = new SampleBOEntity(id);

DataSet dsEntity = boEntity.EntityDataSet;

 

foreach (DataRow dr in dsEntity.Tables["tPrimary"].Rows)

{

 

    DataRow[] chRows = dr.GetChildRows("PrimaryToForeign");

    dr.BeginEdit();

    foreach (DataRow drch in chRows)

    {

        drch.BeginEdit();

        drch["SDescription"] = "Updated Foreign Row";

        drch.EndEdit();

    }

    dr["Pdescription"] = "Update Primary Row";

    dr.EndEdit();

}

 

boEntity.SaveEntity();

System.Windows.MessageBox.Show("data saved to databse successfully");

 

Step 9: Code to fetch and delete the rows:

long id = Convert.ToInt64(txtID.Text);

SampleBOEntity boEntity = new SampleBOEntity(id);

boEntity.Delete();

System.Windows.MessageBox.Show("Records deleted from databse successfully");

 

Summary: Something in the software development needs comes when some data only make sense when it exists in group such as primary table data and secondary table date. It is very difficult to make changes in the database for identity columns along with Primary and Foreign table. Here we have learnt how easily we can achieve this functionality with ADO.NET.

 

Note: Download the attached zip file for the sample code and backup of the database used in the sample. Restore the a2zdotnet database into the SQLExpress edition from the backup file and run the sample.

 

Reference:



Keywords :
Tags :
Rate This Article :

Comments :

# 1 Annonymous Wrote on 10/01/2008


Nice article.



Write a Comment / Question / Feedback ...


User Login
Username :
Password :
Register Login

Forgot Password


Related Articles