From: TWischmeier on
Hi,

I have some trouble updating my database. I have two DataTables: one
"main" table and a second table, which contains a copied subset of the
rows of the main table. Some values of non-PK-columns get changed in
the second table and those values are saved back to the main table via
Table.Merge(). Up to here all seems to work properly, as the affected
rows in the main table all contain the new values and have the
RowStatus "Modified".

I then invoke DataAdapter.Update(Table) with the main table. This call
returns the expected number of rows which were to be updated, but the
values do not get updated in the table (I checked this via
QueryAnalyzer). Subsequently, DataAdapter.Fill(Table) overwrites the
Table with the old values. Also, the DataAdapter.RowUpdated event does
not fire (I hooked up to see if it would).

The DataAdapter is bound to a single table and I use the
SqlCECommandBuilder for retrieving the corresponding Delete / Insert /
Update commands.

Where am I going wrong, what options do I have to narrow the problem
down further? .NETCF version ist 3.5, as is the SqlCE Version. OS is
Windows Mobile 6 Professional on the device emulator.
From: TWischmeier on
I was able to trace the problem further. All the .Merge()
and .Update() Methods are working fine, the problem is where the
values in the second DataTable are changed.

Those second DataTable is bound to a DataGrid. There I use a custom
class to display a checkbox for Boolean values, so the user can change
those directly in the DataGrid. The class for that CheckBox is dervice
from DataGridColumnStyle. I bind the CheckState-Property of the
CheckBox like that:

_checkBox.DataBindings.Add("CheckState", Owner.DataSource,
MappingName, true, DataSourceUpdateMode.OnPropertyChanged,
this.NullValue);

Where Owner is the DataGrid and MappingName is the respective
ColumnName. If I tick the checkbox and debug into the code, the value
is set correctly in the DataTable but the corresponding row remains in
RowState "unchanged", so any following Updates do not produce any
results.

I also tested it "manually", where I would debug through the code
without preceeding changes of the values in the DataGrid but changing
those values programatically just before the .Merge()-Call. That works
perfectly, so my problem really is:

Why does the RowState stay "Unchanged" even when there was a change
through the binding?


On 9 Mrz., 17:00, TWischmeier <tim.wischme...(a)googlemail.com> wrote:
> Hi,
>
> I have some trouble updating my database. I have two DataTables: one
> "main" table and a second table, which contains a copied subset of the
> rows of the main table. Some values of non-PK-columns get changed in
> the second table and those values are saved back to the main table via
> Table.Merge(). Up to here all seems to work properly, as the affected
> rows in the main table all contain the new values and have the
> RowStatus "Modified".
>
> I then invoke DataAdapter.Update(Table) with the main table. This call
> returns the expected number of rows which were to be updated, but the
> values do not get updated in the table (I checked this via
> QueryAnalyzer). Subsequently, DataAdapter.Fill(Table) overwrites the
> Table with the old values. Also, the DataAdapter.RowUpdated event does
> not fire (I hooked up to see if it would).
>
> The DataAdapter is bound to a single table and I use the
> SqlCECommandBuilder for retrieving the corresponding Delete / Insert /
> Update commands.
>
> Where am I going wrong, what options do I have to narrow the problem
> down further? .NETCF version ist 3.5, as is the SqlCE Version. OS is
> Windows Mobile 6 Professional on the device emulator.

From: TWischmeier on
Well, after a lot more debugging and some intimate hours with the .NET
Reflector I was finally able to narrow the problem down. The
SetValue()-Method of the DataRowPropertyDescriptor (which is invoked
by the Binding of the corresponding Control in the DataGrid after
changing a value) does invoke BeginEdit() on the DataRow, but not
EndEdit() (at least I did not find a place where that method should be
called). So before issuing any further actions I did a

Table.Select().Every(row => row.EndEdit());

which did the trick. Obviously when having many rows in the Table this
would issue many unnecessary calls when only a few values get changed
(and I honestly feel this is more like a workaround instead of using
the correct way), so the question is, who would I handle DataBindings
correctly?

On 10 Mrz., 12:18, TWischmeier <tim.wischme...(a)googlemail.com> wrote:
> I was able to trace the problem further. All the .Merge()
> and .Update() Methods are working fine, the problem is where the
> values in the second DataTable are changed.
>
> Those second DataTable is bound to a DataGrid. There I use a custom
> class to display a checkbox for Boolean values, so the user can change
> those directly in the DataGrid. The class for that CheckBox is dervice
> from DataGridColumnStyle. I bind the CheckState-Property of the
> CheckBox like that:
>
> _checkBox.DataBindings.Add("CheckState", Owner.DataSource,
> MappingName, true, DataSourceUpdateMode.OnPropertyChanged,
> this.NullValue);
>
> Where Owner is the DataGrid and MappingName is the respective
> ColumnName. If I tick the checkbox and debug into the code, the value
> is set correctly in the DataTable but the corresponding row remains in
> RowState "unchanged", so any following Updates do not produce any
> results.
>
> I also tested it "manually", where I would debug through the code
> without preceeding changes of the values in the DataGrid but changing
> those values programatically just before the .Merge()-Call. That works
> perfectly, so my problem really is:
>
> Why does the RowState stay "Unchanged" even when there was a change
> through the binding?
>
> On 9 Mrz., 17:00, TWischmeier <tim.wischme...(a)googlemail.com> wrote:
>
> > Hi,
>
> > I have some trouble updating my database. I have two DataTables: one
> > "main" table and a second table, which contains a copied subset of the
> > rows of the main table. Some values of non-PK-columns get changed in
> > the second table and those values are saved back to the main table via
> > Table.Merge(). Up to here all seems to work properly, as the affected
> > rows in the main table all contain the new values and have the
> > RowStatus "Modified".
>
> > I then invoke DataAdapter.Update(Table) with the main table. This call
> > returns the expected number of rows which were to be updated, but the
> > values do not get updated in the table (I checked this via
> > QueryAnalyzer). Subsequently, DataAdapter.Fill(Table) overwrites the
> > Table with the old values. Also, the DataAdapter.RowUpdated event does
> > not fire (I hooked up to see if it would).
>
> > The DataAdapter is bound to a single table and I use the
> > SqlCECommandBuilder for retrieving the corresponding Delete / Insert /
> > Update commands.
>
> > Where am I going wrong, what options do I have to narrow the problem
> > down further? .NETCF version ist 3.5, as is the SqlCE Version. OS is
> > Windows Mobile 6 Professional on the device emulator.