Sarah:
I think I understand. Ok, whenver you add a value to the Row, it may be in
the db or it may not. Assuming it's not in there, a simple insert command
will work. But if it is, that causes some drama. So here's esssentially
what I propose. If the data exists in the db, you still want to use the
dataadapter and you want it to use the Update command. However, since it
sees the rowstate as added, it will use the Insert command. If it 'knew' to
use Insert when it didn't exist in the database and rowstate was added and
to use "Update" when it was in the DB and rowstate would be added, life
would be good, correct?
Ok, you'll have to add the value to the row either way b/c if it's not in
the datatable, neither command is going to much matter. So, after adding
the row to the datatable, run a function that returns whether or not the row
was in the db. If it is already in there, Immediately call .AcceptChanges
only on THAT ROW. Otherwise no acceptchanges is necessary
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemdatadatarowclassacceptchangestopic.asp.
So, you add a row and it happens to exist in the db. Right after you add it
to the db, you call your function (something like DoesValueExist) which
returns True (indicating it does). Currenlty the rowstate is added. So,
the very next line you call NewlyAddedDataRow.AcceptChanges (only on this
row). Now the Rowstate is unchanged. Anything you do to this row will cause
its rowstate to be Modified... After calling AcceptChanges, Rowstate won't
ever be added unless you delete or remove it and add it again. So, you
change the values, call dataAdapter.UPdate(dataset) and then it will see a
rowstate or modified, call the Update command instead of Insert, and life
should be good.
Now, you add another new row which isn't in the db. Immediately afterward
you call DoesValueExist and it returns false. In this instance, the
Rowstate is currently Added and you want it to remain that way. You may
still need to change some values, but the final values are what you want and
you need it to be inserted into the db. So, you call update, the adapter
sees the rowstate as added, and calls the InsertCommand as planned.
The whole thing is governed by checking if it exists immediately after you
add the row. If it does, call AcceptChanges which makes it as though it
came from the db originally. If it doesn't, then leave the rowstate aalone.
In doing so, the rowstate of your datatable will match the db which is what
you want. The whole prolem is that they are out of sync at times but
calling acceptchanges on any row that already exists will set it to
UnChanged which is what you want (it's what happens when you call
dataadapter.Fill with the default setting of AcceptChangesDuringFill set to
false.)
Does this make sense? Basically, you are just using AcceptChanges to make
sure the datatable matches the db as closely as possible, and in doing so,
you can use the Update/Insert/Delete command as you would normally.
Let me know if you have any problems. Sorry about the delay. I'll keep my
eyes open for your response.
Bill
Thanks again for your help.
In my application the majority of the data comes from another application
which is run before it. These two application are tightly integrated via
XML. So, the application can get data these ways:
1) Via XML from the other app including some user input (majority of the
time)
2) Via the app database (updating a current record)
3) User input
I have no problem with 2 because I fill my datasets and when I change the
data my rowstate equals "modified". And when I call update my dataadapter
it calles my update command. The problem I have is with 1 and 3 because the
record could already be in the database (App does not know - I can test it
before insert). My datasets rowstate equals "added" and of coarse the
dataadapter calls the insert command. I can create a stored procedure that
can test for the record and if exists then update it. This works fine
however I do not like tricking to the application. I could design the
application not to use the data adpater and just manually pass the
parameters. The real problem I run into is one of my tables is designed to
have multiple child tables. There are times when these tables do not have
any data in them which means the keys in the main table are null. So, on
the update I would need at times to delete data (rows) which I could really
use the dataadpater and the three comands (insert, update and delete). This
could simplify my updating logic if I could somehow make the rowstate work.
I hoped I explained my situation.
Thanks again.
if
I
can find anything. The rowstate mechanism is one of the most robust
features and while I'm not implying there can't be any bugs or issues, I
know of none and I'm fairly active in this regard. If you are submitting
the row in an update statement and it's being inserted, then the rowstate
should no longer indicate added. If you change anything to it, it
should
be
modified. If it's still showing added, I suspect that you may have an
exception being raised that you are just eating thereby giving the
appearance that it's updated when it's not or some other type problem. Just
to be safe, I'd call update, for testing purposes I'd fire another query
just to verify unquestionably that it worked, then I'd try an edit. So
assuming we are talking about Row 0 in datatable, I'd do the following:
Debug.Assert(dt.Rows[0].RowState == RowState.Added); file://Call this before
update. This assertion should pass
next, call the update
int i = dataAdapter.Update(dt);
Now, make sure you are catching any exceptions here and not eating them..
Verify something happened:
Debug.Assert(i > 0);
file://If this fails, the update didn't work as expected. Assuming it
did
the
rowstate should be Unchanged
Debug.Assert(dt.Rows[0].RowState == RowState.Unchanged);
This too should pass. If it fails, but the other assertions didn't,
something weird is happening.
Ok, but assume it does, just for the sake of addressing this one
issue,
call
AcceptChanges just to be sure, then check the rowstate again There is the
possilibity that the row is being modified in another thread or if you
created an event, then it's firing before we check again.
dt.AcceptChanges();
Now,check the rowstate again... All of the assertions should pass but if
they don't, somethign else like what I mention above may be at play.
If
so,
then send me the code it you'd like and I'll take a look at it.
However,based on our earlier dialog, I think the insert may be failing b/c
it already exists so you may need to check beforehand or use some other
mechanism.
Let me know if you need any help.
Bill
Thanks,
I agree with you I think in my case I cannot use the data adapter but
rather
create my own logic. I have tested using the data adapter and it never
fires the update command when I manually enter in the data even if
the
the
data exists in the db. I can never get the rowstate to be equal to
"modified" when I change the data on my manually added data row
after
it rowstate true.
If be
no b/c
the
when
in different
from that
row