|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Updating a Dataset: How the Adapter works inside ?Hello,
I am currently writing a DAL. When calling the DataAdapter.Update function for a Dataset, does the DataAdapter calls DataSet.GetChanges() internally before looping through rows? Or should my DAL be responsible to call GetChanges before updating? Thank you (I am talking about a single table dataset, disregarding the cases where the GetChanges must be called for multiple tables datasets) It will only update rows with changes, if that is what you are asking. You
may want to call GetChanges first, if for example you have a web service updating the data, and you only want to send the rows with changes for performance reasons. Show quote "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... > Hello, > > I am currently writing a DAL. When calling the DataAdapter.Update > function > for a Dataset, does the DataAdapter calls DataSet.GetChanges() internally > before looping through rows? Or should my DAL be responsible to call > GetChanges before updating? > > Thank you > > (I am talking about a single table dataset, disregarding the cases where > the > GetChanges must be called for multiple tables datasets) > Thank you Marina but not quite what I was asking.
I know the DataAdapter.Update only updates the rows with changes, what I am wondering is if the it loops through all the rows it receives or only loops thorugh the rows with changes. Thansk anyway Show quote "Marina" wrote: > It will only update rows with changes, if that is what you are asking. You > may want to call GetChanges first, if for example you have a web service > updating the data, and you only want to send the rows with changes for > performance reasons. > > "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message > news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... > > Hello, > > > > I am currently writing a DAL. When calling the DataAdapter.Update > > function > > for a Dataset, does the DataAdapter calls DataSet.GetChanges() internally > > before looping through rows? Or should my DAL be responsible to call > > GetChanges before updating? > > > > Thank you > > > > (I am talking about a single table dataset, disregarding the cases where > > the > > GetChanges must be called for multiple tables datasets) > > > > > You may want to check out this article...a good example of creating
DAL's IMHO. http://msdn.microsoft.com/msdnmag/issues/02/02/data/default.aspx He creates a dataset of only the changes before doing the update to reduce network traffic...according to the article. I am new to all of this and struggling with designing my own DAL process. Coming from DAO and recordsets, it is a stretch of the imagination...so many ways to do things. John On Tue, 29 Mar 2005 04:47:02 -0800, "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote: Show quote >Thank you Marina but not quite what I was asking. > >I know the DataAdapter.Update only updates the rows with changes, what I am >wondering is if the it loops through all the rows it receives or only loops >thorugh the rows with changes. > >Thansk anyway > >"Marina" wrote: > >> It will only update rows with changes, if that is what you are asking. You >> may want to call GetChanges first, if for example you have a web service >> updating the data, and you only want to send the rows with changes for >> performance reasons. >> >> "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message >> news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... >> > Hello, >> > >> > I am currently writing a DAL. When calling the DataAdapter.Update >> > function >> > for a Dataset, does the DataAdapter calls DataSet.GetChanges() internally >> > before looping through rows? Or should my DAL be responsible to call >> > GetChanges before updating? >> > >> > Thank you >> > >> > (I am talking about a single table dataset, disregarding the cases where >> > the >> > GetChanges must be called for multiple tables datasets) >> > >> >> >> Does that really matter?
To get a list of all the rows with changes, it has to first loop through all the rows anyway to find all the ones with changes. So it all amounts to the same amt of work, whether you loop through, get all the changes, and hand it off to the adapter, or whether it does it on its own. I supposed they could have a more complicated scheme of adding rows to various collections to keep track of added, updated, etc, rows. You can find a decompiler and look at the internal code - if you really care that much. But does it really matter? Show quote "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message news:194E0DAC-F798-48B3-9644-427D8C75F108@microsoft.com... > Thank you Marina but not quite what I was asking. > > I know the DataAdapter.Update only updates the rows with changes, what I > am > wondering is if the it loops through all the rows it receives or only > loops > thorugh the rows with changes. > > Thansk anyway > > "Marina" wrote: > >> It will only update rows with changes, if that is what you are asking. >> You >> may want to call GetChanges first, if for example you have a web service >> updating the data, and you only want to send the rows with changes for >> performance reasons. >> >> "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in >> message >> news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... >> > Hello, >> > >> > I am currently writing a DAL. When calling the DataAdapter.Update >> > function >> > for a Dataset, does the DataAdapter calls DataSet.GetChanges() >> > internally >> > before looping through rows? Or should my DAL be responsible to call >> > GetChanges before updating? >> > >> > Thank you >> > >> > (I am talking about a single table dataset, disregarding the cases >> > where >> > the >> > GetChanges must be called for multiple tables datasets) >> > >> >> >> Marina,
IMHO it does matter. For instance, if you receive a Dataset with thousands of records where only a dozen need updating. Keeping the discussion in context, I was talking exclusively about DAL programming. It is obvious that passing thousands of records to the Data Layer when only a few records need update is poor Business Layer programming, specially if the Data Layer is a separate Tier. As you said, the DataAdapter might loop the dataset anyway, but also, as you said, it is likely the DataSet has an optimized internal implementation. I have posted another topic "Updating a Dataset 2nd Part" where I really explain why I made this question in the first place. It has to do with keeping track of the success updates per DataRow, a neat feature, easy to implement. Such implementation is much easier if the DataSet passed to the DataAdapter.Update method is the same DataSet received from the Business Layer. However when calling the GetChanges method, we are creating a copy, lossing the update success tracking per Row: myDataAdapter.Update(myDataSet); //keeping track of update errors myDataAdapter.Update(myDataSet.GetChanges()); //cannot keep track of update errors I don't want to extend myself in this post ... please check the other one: "Updating a DataSet 2nd Part" Thanks for the answers :) Show quote "Marina" wrote: > Does that really matter? > > To get a list of all the rows with changes, it has to first loop through all > the rows anyway to find all the ones with changes. So it all amounts to the > same amt of work, whether you loop through, get all the changes, and hand it > off to the adapter, or whether it does it on its own. > > I supposed they could have a more complicated scheme of adding rows to > various collections to keep track of added, updated, etc, rows. You can find > a decompiler and look at the internal code - if you really care that much. > But does it really matter? > > "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message > news:194E0DAC-F798-48B3-9644-427D8C75F108@microsoft.com... > > Thank you Marina but not quite what I was asking. > > > > I know the DataAdapter.Update only updates the rows with changes, what I > > am > > wondering is if the it loops through all the rows it receives or only > > loops > > thorugh the rows with changes. > > > > Thansk anyway > > > > "Marina" wrote: > > > >> It will only update rows with changes, if that is what you are asking. > >> You > >> may want to call GetChanges first, if for example you have a web service > >> updating the data, and you only want to send the rows with changes for > >> performance reasons. > >> > >> "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in > >> message > >> news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... > >> > Hello, > >> > > >> > I am currently writing a DAL. When calling the DataAdapter.Update > >> > function > >> > for a Dataset, does the DataAdapter calls DataSet.GetChanges() > >> > internally > >> > before looping through rows? Or should my DAL be responsible to call > >> > GetChanges before updating? > >> > > >> > Thank you > >> > > >> > (I am talking about a single table dataset, disregarding the cases > >> > where > >> > the > >> > GetChanges must be called for multiple tables datasets) > >> > > >> > >> > >> > > > Yes, the dataset can be optimized to not loop. But then odds are, GetChanges
would be optimized in the same way. So it really amounts to the same thing. Who knows - you would have to look. Wouldn't the fastest and easiest way to answer this question if you really care about it, is to run a test to see which way is faster? Show quote "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in message news:9B7AB569-8816-4112-BCFB-B0E222400EA6@microsoft.com... > Marina, > IMHO it does matter. For instance, if you receive a Dataset with thousands > of records where only a dozen need updating. > > Keeping the discussion in context, I was talking exclusively about DAL > programming. > It is obvious that passing thousands of records to the Data Layer when > only > a few records need update is poor Business Layer programming, specially if > the Data Layer is a separate Tier. > > As you said, the DataAdapter might loop the dataset anyway, but also, as > you > said, it is likely the DataSet has an optimized internal implementation. > > I have posted another topic "Updating a Dataset 2nd Part" where I really > explain why I made this question in the first place. It has to do with > keeping track of the success updates per DataRow, a neat feature, easy to > implement. > > Such implementation is much easier if the DataSet passed to the > DataAdapter.Update method is the same DataSet received from the Business > Layer. However when calling the GetChanges method, we are creating a copy, > lossing the update success tracking per Row: > > > myDataAdapter.Update(myDataSet); //keeping track of update errors > > myDataAdapter.Update(myDataSet.GetChanges()); //cannot keep track of > update > errors > > I don't want to extend myself in this post ... please check the other one: > "Updating a DataSet 2nd Part" > > Thanks for the answers :) > > "Marina" wrote: > >> Does that really matter? >> >> To get a list of all the rows with changes, it has to first loop through >> all >> the rows anyway to find all the ones with changes. So it all amounts to >> the >> same amt of work, whether you loop through, get all the changes, and hand >> it >> off to the adapter, or whether it does it on its own. >> >> I supposed they could have a more complicated scheme of adding rows to >> various collections to keep track of added, updated, etc, rows. You can >> find >> a decompiler and look at the internal code - if you really care that >> much. >> But does it really matter? >> >> "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in >> message >> news:194E0DAC-F798-48B3-9644-427D8C75F108@microsoft.com... >> > Thank you Marina but not quite what I was asking. >> > >> > I know the DataAdapter.Update only updates the rows with changes, what >> > I >> > am >> > wondering is if the it loops through all the rows it receives or only >> > loops >> > thorugh the rows with changes. >> > >> > Thansk anyway >> > >> > "Marina" wrote: >> > >> >> It will only update rows with changes, if that is what you are asking. >> >> You >> >> may want to call GetChanges first, if for example you have a web >> >> service >> >> updating the data, and you only want to send the rows with changes for >> >> performance reasons. >> >> >> >> "Abelardo Vacca" <AbelardoVa***@discussions.microsoft.com> wrote in >> >> message >> >> news:514665B9-9A30-49C0-A5BC-39C945FDEAAA@microsoft.com... >> >> > Hello, >> >> > >> >> > I am currently writing a DAL. When calling the DataAdapter.Update >> >> > function >> >> > for a Dataset, does the DataAdapter calls DataSet.GetChanges() >> >> > internally >> >> > before looping through rows? Or should my DAL be responsible to call >> >> > GetChanges before updating? >> >> > >> >> > Thank you >> >> > >> >> > (I am talking about a single table dataset, disregarding the cases >> >> > where >> >> > the >> >> > GetChanges must be called for multiple tables datasets) >> >> > >> >> >> >> >> >> >> >> >> Abelardo,
You make me curious. > Why not it has all the information from the original dataset and it is only > myDataAdapter.Update(myDataSet.GetChanges()); //cannot keep track of > update > errors > a copy. The original datarow when there is an error can easily be found in the original dataset by using a datarowcollection find in my opinion. Therefore enlighten me what I miss? Cor > Why not it has all the information from the original dataset and it is only The short answer: Because it is a copy, GetChanges generates a subset of the > a copy. rows in an entirely different DataSet. The DataRow.RowError information is there, but in the copy, not in the original DataSet. For the long answer I am copying this from my other post: When updating a SINGEL TABLE Dataset I keep track of the rows that were succesfully updated , but it does not look the slickest solution when working with MULTIPLE RELATED TABLES. Here is what I do (quite simple): 1. Registering my adapter to handle the RowUpdated event: myDataAdapter.RowUpdated +=new OleDbRowUpdatedEventHandler(myDataAdapter_RowUpdated); 2. Handling the RowUpdated event to store the error message and skip the AcceptChanges call: private static void myDataAdapter_RowUpdated(object sender, OleDbRowUpdatedEventArgs e) { if (e.Status == UpdateStatus.ErrorsOccurred) { e.Row.RowError = e.Errors.Message; e.Status = UpdateStatus.SkipCurrentRow; } } 3. And last, simply updating the data set: myDataAdapter.Update(myDataSet); Since "SkipCurrentRow" will skip the call to DataRow.AcceptChanges(), the resulting dataset (after it has been updated) will keep the RowState for those rows where an error ocurred, the rest of the rows will have a "Unchanged" state. This is all great!!! Now, in a multiple tables datasets with relationships among the tables, the DataSet.GetChanges() method is a MUST to control the order in which updates are performed. The question is: --- How do I get the same behaviour of keeping track of the rows that were sucessfully updated ? Since when using DataSet.GetChanges(), I am sending copies of the DataSet to the DataAdapter.Update (instead of passign the DataSet itself), then the RowState and RowError are not stored in my original DataSet. --- My solution so far involves merging the copies of the DataSet with the original DataSet. This works, but to a certain extend: DataSet originalDS; DataSet deletedDS = originalDS.GetChanges(DataRowState.Deleted); DataSet modifiedDS = originalDS.GetChanges(DataRowState.Added |DataRowState.Modified); originalDS.AcceptChanges(); //reseting the row statesmyDataAdapter2.Update(deletedDS, "Table2"); myDataAdapter1.Update(deletedDS, "Table1"); originalDS.Merge(deletedDS); //getting the Errors copied into the original DS myDataAdapter1.Update(modifiedDS, "Table1"); myDataAdapter2.Update(modifiedDS, "Table2"); originalDS.Merge(modifiedDS); //getting the Errors copied into the original DS At this point my DataSet has the RowError messages, BUT the RowStates for the Rows with Error are all set Modified, instead of Added, Deleted or Modified (This is the effect of performing the DataSet.Merge.) Compared to the single table DataSet, this solution is a pain, and the only way I see around it would be looping right after each Merge, yet worse, updating Modified and Added rows separately!!! Thanks for your opinions .... and for reading this far :) Show quote >"Cor Ligthert" wrote: > Abelardo, > > You make me curious. > > > > myDataAdapter.Update(myDataSet.GetChanges()); //cannot keep track of > > update > > errors > > > Why not it has all the information from the original dataset and it is only > a copy. > > The original datarow when there is an error can easily be found in the > original dataset by using a datarowcollection find in my opinion. > > Therefore enlighten me what I miss? > > Cor > > > > However they have the same primary keys, I really not see the point. when an > The short answer: Because it is a copy, GetChanges generates a subset of > the > rows in an entirely different DataSet. The DataRow.RowError information is > there, but in the copy, not in the original DataSet. > error is catched and I know the row, than I know in my opinion the original. Tell me what I miss? Cor Hi Cor,
> when an error is catched and I know the row, than I know in my opinion the Well put, and it is true. But remember I am talking about building a DAL. > original. The code exposed in these samples is not intended for a small application where you can find Data Access Logic in the Forms, but for an N-Layer architecture where The programmer who will use the Data Access Layer Components, and send the original DataSet will only see something like this: CustomersDALC.Update(myCustomersDataSet); This "myCustomersDataSet" is my 'original' dataset within the DALC method: public void Update(DataSet myDataSet) { .... code preparing the DataAdapter myDataAdapter.Update(myDataSet); // cool, I am using the original } what if it is a multiple table Dataset with relationships: public void Update(DataSet myDataSet) { .... code preparing the DataAdapterS myDataAdapter1.Update(myDataSet.GetChanges(deleted), "Table1"); myDataAdapter2.Update(myDataSet.GetChanges(deleted), "Table2"); ... the rest of the code for modified and added rows ... now myDataSet does not reflect the RowErrors. } Cor, while it is true the RowErrors are available to me within the customersDALC.Update method, what I really need to do is make them available to the caller (Business Layer in most cases) As I posted before, the process of using Merge is kind of messy .... I am hoping for a cleaner option. Thanks Show quote "Cor Ligthert" wrote: > > > > The short answer: Because it is a copy, GetChanges generates a subset of > > the > > rows in an entirely different DataSet. The DataRow.RowError information is > > there, but in the copy, not in the original DataSet. > > > However they have the same primary keys, I really not see the point. when an > error is catched and I know the row, than I know in my opinion the original. > Tell me what I miss? > > Cor > > > Abelardo,
I get the idea that we are reaching the end. > This "myCustomersDataSet" is my 'original' dataset within the DALC method: This is a "reference" to your original dataset (assuming you do it by value) > and therefore completly usable. It is not a passing of a dataset itself. It is completly the refrence to the original dataset and therefore you can do what you want with it. Cor Hi Cor,
> This is a "reference" to your original dataset (assuming you do it by value) Indeed. We do not disagree on this. I can do what I want with this DataSet, > and therefore completly usable. It is not a passing of a dataset itself. It > is completly the refrence to the original dataset and therefore you can do > what you want with it. the issue was HOW to do it. I do not particulary like the way I am doing it now (using the DataSet.Merge.) |
|||||||||||||||||||||||