DataSet Relation Exception Issue

G

Guest

I have a situation where I need to add rows to tables with a Parent-Child
relationship which presents a constraints violation when I reject the
changes. Here is the scenario:

I add a row to a Parent table which then causes a row to be added to the
Child table referencing the parent row. The Child table rows can be modified
by multiple processes so I need to manage row additionals separate from row
modifications in terms of how they are canceled or rejected. When I need to
cancel the changes for the child added rows I step through and identify the
added rows and RejectChanges() for each. I can do the same process for the
parent table added rows. However, if I RejectChanges() for the Parent table
as a whole I get the following error:
"Cannot make this change because constraints are enforced on relation
ParentToChild, and changing this value will strand child rows."

The Child table added rows have all been removed prior to the Parent table
RejectChanges() call so it doesn't make any sense to me. I've assemble the
following example to illustrate the problem. Is this a .NET bug or am I doing
something incorrectly here.

public void TestProblem()
{
int intKey = 1;

// Create DataSet with Parent and Child tables
DataSet ds = CreateDataSet();

// Add Parent and Child to tables
AddRow( ds.Tables["Parent"], intKey );
AddRow( ds.Tables["Child"], intKey );
ds.AcceptChanges();

// Add another Child to first parent
AddRow( ds.Tables["Child"], intKey );
// Add another Parent and Child to tables
AddRow( ds.Tables["Parent"], ++intKey );
AddRow( ds.Tables["Child"], intKey );

// Roll back added Child rows
RollBackAdded( ds.Tables["Child"] );
// Roll back added Parent rows
RollBackAdded( ds.Tables["Parent"] );

// Roll back added Parent rows
ds.Tables["Parent"].RejectChanges();
}

public DataSet CreateDataSet()
{
DataSet ds = new DataSet();

// Create Parent Table
DataTable dtParent = new DataTable("Parent");
DataColumn dc = dtParent.Columns.Add("key", typeof(Int32));
dc.AllowDBNull = false;
dc.Unique = true;
dtParent.Columns.Add("Name", typeof(String));
ds.Tables.Add(dtParent);

// Create Child Table
DataTable dtChild = new DataTable("Child");
dc = dtChild.Columns.Add("key", typeof(Int32));
dc.AllowDBNull = false;
dtChild.Columns.Add("Name", typeof(String));
ds.Tables.Add(dtChild);

ds.Relations.Add("ParentToChild", dtParent.Columns["key"],
dtChild.Columns["key"] );
return ds;
}

public DataRow AddRow( DataTable dt, int key )
{
DataRow dr = dt.NewRow();
dr["key"] = key;
dr["Name"] = dt.TableName + " " + key.ToString();
dt.Rows.Add(dr);
dr.EndEdit();
return dr;
}

public void RollBackAdded( DataTable dt )
{
// Roll back Added or Deleted rows
DataTable dtChanged = dt.GetChanges();
if( dtChanged != null )
{
DataRow [] dra = new DataRow[dtChanged.Rows.Count];
int no = 0;
foreach( DataRow dr in dtChanged.Rows )
if( dr.RowState == DataRowState.Added || dr.RowState ==
DataRowState.Deleted )
dra[no++] = dr;

for( int jo = 0; jo < no; jo++ )
dra[jo].RejectChanges();
}
}
 
G

Guest

Well, once again, going through the process of documenting my issue I found
the solution. The problem was that I was using the GetChanges() for the
tables which was returning a copy of the affected rows. Rejecting the changes
on these rows did not affect the rows in the original DataSet. Once I removed
the use of this method and resorted to searching the original tables for the
affected rows and applying the RejectChanges() to them the exception went
away. All is well.

Fleckman said:
I have a situation where I need to add rows to tables with a Parent-Child
relationship which presents a constraints violation when I reject the
changes. Here is the scenario:

I add a row to a Parent table which then causes a row to be added to the
Child table referencing the parent row. The Child table rows can be modified
by multiple processes so I need to manage row additionals separate from row
modifications in terms of how they are canceled or rejected. When I need to
cancel the changes for the child added rows I step through and identify the
added rows and RejectChanges() for each. I can do the same process for the
parent table added rows. However, if I RejectChanges() for the Parent table
as a whole I get the following error:
"Cannot make this change because constraints are enforced on relation
ParentToChild, and changing this value will strand child rows."

The Child table added rows have all been removed prior to the Parent table
RejectChanges() call so it doesn't make any sense to me. I've assemble the
following example to illustrate the problem. Is this a .NET bug or am I doing
something incorrectly here.

public void TestProblem()
{
int intKey = 1;

// Create DataSet with Parent and Child tables
DataSet ds = CreateDataSet();

// Add Parent and Child to tables
AddRow( ds.Tables["Parent"], intKey );
AddRow( ds.Tables["Child"], intKey );
ds.AcceptChanges();

// Add another Child to first parent
AddRow( ds.Tables["Child"], intKey );
// Add another Parent and Child to tables
AddRow( ds.Tables["Parent"], ++intKey );
AddRow( ds.Tables["Child"], intKey );

// Roll back added Child rows
RollBackAdded( ds.Tables["Child"] );
// Roll back added Parent rows
RollBackAdded( ds.Tables["Parent"] );

// Roll back added Parent rows
ds.Tables["Parent"].RejectChanges();
}

public DataSet CreateDataSet()
{
DataSet ds = new DataSet();

// Create Parent Table
DataTable dtParent = new DataTable("Parent");
DataColumn dc = dtParent.Columns.Add("key", typeof(Int32));
dc.AllowDBNull = false;
dc.Unique = true;
dtParent.Columns.Add("Name", typeof(String));
ds.Tables.Add(dtParent);

// Create Child Table
DataTable dtChild = new DataTable("Child");
dc = dtChild.Columns.Add("key", typeof(Int32));
dc.AllowDBNull = false;
dtChild.Columns.Add("Name", typeof(String));
ds.Tables.Add(dtChild);

ds.Relations.Add("ParentToChild", dtParent.Columns["key"],
dtChild.Columns["key"] );
return ds;
}

public DataRow AddRow( DataTable dt, int key )
{
DataRow dr = dt.NewRow();
dr["key"] = key;
dr["Name"] = dt.TableName + " " + key.ToString();
dt.Rows.Add(dr);
dr.EndEdit();
return dr;
}

public void RollBackAdded( DataTable dt )
{
// Roll back Added or Deleted rows
DataTable dtChanged = dt.GetChanges();
if( dtChanged != null )
{
DataRow [] dra = new DataRow[dtChanged.Rows.Count];
int no = 0;
foreach( DataRow dr in dtChanged.Rows )
if( dr.RowState == DataRowState.Added || dr.RowState ==
DataRowState.Deleted )
dra[no++] = dr;

for( int jo = 0; jo < no; jo++ )
dra[jo].RejectChanges();
}
}
 

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