|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
GetChildRows - Finding Deleted ChildRows ?I've got a scenario that i can't seem to find a way around. I have an order/detail type setup. My Order record is unmodified, but I have detail records that have been deleted. When i say : oDR_MyOrderRecord.GetChildRows("somechildRelation") GetChildRows does not return any of the deleted rows. I have tried using the DataRowVersion = Original syntax, and still I can't find the child rows. Am I doing something wrong? Is this a hole in datasets, where i can't find the deleted child rows to call accept changes on them ? Or, if can't get to the child rows, shouldn't calling AcceptChanges() on the record for the order row make the deleted rows dissapear / detach ? Regards, -eric Eric,
By default, the DataRow.AcceptChanges call will not cascade down to related child rows. You can force the call to cascade down by setting the ForeignKeyConstraint object's AcceptRejectRule property to Cascade: MyRelation.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Accept Back to the original question regarding GetChildRows and deleted rows. The best way to access the deleted child rows would be to use a DataView. I've included some code at the end of this post that I hope proves helpful. David Sceppa Microsoft This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use. © 2005 Microsoft Corporation. All rights reserved. DataSet ds = new DataSet(); DataTable tblParent = ds.Tables.Add("Parent"); tblParent.Columns.Add("ParentID", typeof(int)); tblParent.LoadDataRow(new object[] {1}, true); DataTable tblChild = ds.Tables.Add("Child"); tblChild.Columns.Add("ParentID", typeof(int)); tblChild.Columns.Add("ChildID", typeof(int)); tblChild.LoadDataRow(new object[] {1, 1}, true); tblChild.LoadDataRow(new object[] {1, 2}, true); ds.Relations.Add(tblParent.Columns["ParentID"], tblChild.Columns["ParentID"]); tblChild.Rows[1].Delete(); DataView vueParent = new DataView(tblParent); DataView vueChildren = vueParent[0].CreateChildView(ds.Relations[0]); vueChildren.RowStateFilter = DataViewRowState.Deleted; foreach (DataRowView row in vueChildren) Console.WriteLine(row["ChildID"]); David,
Thanks for the tip about accept changes. I actually have function that takes care of accept changed (shallow vs. deep) because i flip back and forth all the time. It would be impractical to turn the setting on/off across the entire hierarcy of tables i'm working with. I know I can create a dataview to get to child rows in a deleted state. However, the problem here is that creating a dataview is way more expensive an operation than i can afford. GetChildRows() seems to be precalcualated when the dataset is populated. When i traced with Devpartners GetChildRows as at least 10x faster then building a dataview and sometimes even more if the data being searched is large enough. So, i go back to my original scenario: Order /Detail setup. Order record is unchanged, a detail row is marked as deleted. Saying OrderRow.GetChildRows("Order_has_Details") does not give me a handle to the deleted child rows. Even saying OrderRow.GetChildRows("Order_has_Details", Original) does not give me a handle to the deleted child rows. Isn't this a bug in the way data relations are hadled ? The documentation on getChildRows is not nearly detailed enough to account for this situation. If it isn't a bug, isn't it at least a gaping hole in how datarelations work ? No way to get to rows that are for the time being "soft deleted", via the relationship sure seems like a problem to me. Regards, -eric Is David Sceppa wrote: Show quoteHide quote > Eric, > > By default, the DataRow.AcceptChanges call will not cascade down to > related child rows. You can force the call to cascade down by setting the > ForeignKeyConstraint object's AcceptRejectRule property to Cascade: > > MyRelation.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Accept > > Back to the original question regarding GetChildRows and deleted rows. > The best way to access the deleted child rows would be to use a DataView. > I've included some code at the end of this post that I hope proves helpful. > > David Sceppa > Microsoft > This posting is provided "AS IS" with no warranties, > and confers no rights. You assume all risk for your use. > © 2005 Microsoft Corporation. All rights reserved. > > DataSet ds = new DataSet(); > DataTable tblParent = ds.Tables.Add("Parent"); > tblParent.Columns.Add("ParentID", typeof(int)); > tblParent.LoadDataRow(new object[] {1}, true); > > DataTable tblChild = ds.Tables.Add("Child"); > tblChild.Columns.Add("ParentID", typeof(int)); > tblChild.Columns.Add("ChildID", typeof(int)); > tblChild.LoadDataRow(new object[] {1, 1}, true); > tblChild.LoadDataRow(new object[] {1, 2}, true); > > ds.Relations.Add(tblParent.Columns["ParentID"], > tblChild.Columns["ParentID"]); > > tblChild.Rows[1].Delete(); > > DataView vueParent = new DataView(tblParent); > DataView vueChildren = vueParent[0].CreateChildView(ds.Relations[0]); > vueChildren.RowStateFilter = DataViewRowState.Deleted; > foreach (DataRowView row in vueChildren) > Console.WriteLine(row["ChildID"]); > David,
Thanks for the tip about accept changes. I actually have function that takes care of accept changed (shallow vs. deep) because i flip back and forth all the time. It would be impractical to turn the setting on/off across the entire hierarchy of tables I'm working with. I know I can create a data view to get to child rows in a deleted state. However, the problem here is that creating a data view is way more expensive an operation than i can afford. GetChildRows() seems to be pre-calcualated when the dataset is populated. When i traced with Dev Partners GetChildRows as at least 10x faster then building a data view and sometimes even more if the data being searched is large enough. So, i go back to my original scenario: Order /Detail setup. Order record is unchanged, a detail row is marked as deleted. Saying OrderRow.GetChildRows("Order_has_Details") does not give me a handle to the deleted child rows. Even saying OrderRow.GetChildRows("Order_has_Details", Original) does not give me a handle to the deleted child rows. Isn't this a bug in the way data relations are handled ? The documentation on getChildRows is not nearly detailed enough to account for this situation. If it isn't a bug, isn't it at least a gaping hole in how data relations work ? No way to get to rows that are for the time being "soft deleted", via the relationship sure seems like a problem to me. Regards, -eric Is David Sceppa wrote: Show quoteHide quote > Eric, > > By default, the DataRow.AcceptChanges call will not cascade down to > related child rows. You can force the call to cascade down by setting the > ForeignKeyConstraint object's AcceptRejectRule property to Cascade: > > MyRelation.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Accept > > Back to the original question regarding GetChildRows and deleted rows. > The best way to access the deleted child rows would be to use a DataView. > I've included some code at the end of this post that I hope proves helpful. > > David Sceppa > Microsoft > This posting is provided "AS IS" with no warranties, > and confers no rights. You assume all risk for your use. > © 2005 Microsoft Corporation. All rights reserved. > > DataSet ds = new DataSet(); > DataTable tblParent = ds.Tables.Add("Parent"); > tblParent.Columns.Add("ParentID", typeof(int)); > tblParent.LoadDataRow(new object[] {1}, true); > > DataTable tblChild = ds.Tables.Add("Child"); > tblChild.Columns.Add("ParentID", typeof(int)); > tblChild.Columns.Add("ChildID", typeof(int)); > tblChild.LoadDataRow(new object[] {1, 1}, true); > tblChild.LoadDataRow(new object[] {1, 2}, true); > > ds.Relations.Add(tblParent.Columns["ParentID"], > tblChild.Columns["ParentID"]); > > tblChild.Rows[1].Delete(); > > DataView vueParent = new DataView(tblParent); > DataView vueChildren = vueParent[0].CreateChildView(ds.Relations[0]); > vueChildren.RowStateFilter = DataViewRowState.Deleted; > foreach (DataRowView row in vueChildren) > Console.WriteLine(row["ChildID"]); > David,
Thanks for the tip about accept changes. I actually have function that takes care of accept changed (shallow vs. deep) because i flip back and forth all the time. It would be impractical to turn the setting on/off across the entire hierarchy of tables I'm working with. I know I can create a data view to get to child rows in a deleted state. However, the problem here is that creating a data view is way more expensive an operation than i can afford. GetChildRows() seems to be pre-calcualated when the dataset is populated. When i traced with Dev Partners GetChildRows as at least 10x faster then building a data view and sometimes even more if the data being searched is large enough. So, i go back to my original scenario: Order /Detail setup. Order record is unchanged, a detail row is marked as deleted. Saying OrderRow.GetChildRows("Order_has_Details") does not give me a handle to the deleted child rows. Even saying OrderRow.GetChildRows("Order_has_Details", Original) does not give me a handle to the deleted child rows. Isn't this a bug in the way data relations are handled ? The documentation on getChildRows is not nearly detailed enough to account for this situation. If it isn't a bug, isn't it at least a gaping hole in how data relations work ? No way to get to rows that are for the time being "soft deleted", via the relationship sure seems like a problem to me. Regards, -eric Is David Sceppa wrote: Show quoteHide quote > Eric, > > By default, the DataRow.AcceptChanges call will not cascade down to > related child rows. You can force the call to cascade down by setting the > ForeignKeyConstraint object's AcceptRejectRule property to Cascade: > > MyRelation.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Accept > > Back to the original question regarding GetChildRows and deleted rows. > The best way to access the deleted child rows would be to use a DataView. > I've included some code at the end of this post that I hope proves helpful. > > David Sceppa > Microsoft > This posting is provided "AS IS" with no warranties, > and confers no rights. You assume all risk for your use. > © 2005 Microsoft Corporation. All rights reserved. > > DataSet ds = new DataSet(); > DataTable tblParent = ds.Tables.Add("Parent"); > tblParent.Columns.Add("ParentID", typeof(int)); > tblParent.LoadDataRow(new object[] {1}, true); > > DataTable tblChild = ds.Tables.Add("Child"); > tblChild.Columns.Add("ParentID", typeof(int)); > tblChild.Columns.Add("ChildID", typeof(int)); > tblChild.LoadDataRow(new object[] {1, 1}, true); > tblChild.LoadDataRow(new object[] {1, 2}, true); > > ds.Relations.Add(tblParent.Columns["ParentID"], > tblChild.Columns["ParentID"]); > > tblChild.Rows[1].Delete(); > > DataView vueParent = new DataView(tblParent); > DataView vueChildren = vueParent[0].CreateChildView(ds.Relations[0]); > vueChildren.RowStateFilter = DataViewRowState.Deleted; > foreach (DataRowView row in vueChildren) > Console.WriteLine(row["ChildID"]); >
Other interesting topics
DBnull, Date and DataAdapter
Constraint violated but no exception thrown Best way to process millions of records Problem with Update Adapter Really need some help on this Handling very huge data Thread was being aborted Errors typed dataset and sort order on save How can I read a list of files from a folder into a DataTable? MDAC and interop.adodb |
|||||||||||||||||||||||