PC Review


Reply
Thread Tools Rate Thread

dataset updates when primary key changes / concurrency issue

 
 
=?Utf-8?B?SnVzdGluTWFnYXJhbQ==?=
Guest
Posts: n/a
 
      21st Nov 2005
Suppose for a moment I am using "natural" keys and there are the two tables
shown below.

Country (countryName)
LanguageSpokenInCountry (countryName, language)

Suppose I set up cascade updates and deletes between the two tables, in both
the dataset and database, so if a country is renamed, such as from "U.S.A."
to "United States", the corresponding rows in LanguagesSpokenInCountry are
updated.

The default Update commmand for the child table looks something like this:

UPDATE LanguageSpokenInCountry
SET countryName = @countryName, language = @language
WHERE ((countryName = @original_countryName) AND (language =
@original_language))

Now suppose someone modifies the dataset by changing the spelling of
"U.S.A." to "United States" in the parent table, and changes a mis-spelling
of "englsh" to "English" in the corresponding child table row. After the
parent row is updated in the database, the update on the child row fails and
generates a concurrency exception because by the time it gets executed there
is no row in the child table where countryName = the @original_countryName of
"U.S.A."

Now suppose I try to fix this by changing the default Update command to the
following command. Notice that now there WHERE clause looks for countries
matching the current dataset country.

UPDATE LanguageSpokenInCountry
SET countryName = @countryName, language = @language
WHERE ((countryName = @current_countryName) AND (language =
@original_language))

But this is only a partial fix. A problem remains in that whenever the
parent row in the dataset changes, a cascade update in the dataset causes the
child row to be marked as Modified, regardless of whether any other data in
the child row besides the countryName foreign key has changed. As a result,
the data adapter thinks it needs to run the Update command on the child row
when no changes may be necessary. I suppose this could be fixed by
pre-processing all "modified" child rows in the dataset before updating to
look to see if any data actually changed besides the foreign key, and if not,
simply accept the changes on the row. This seems like a hack to me.

What is the recommend way to approach this overall problem?
 
Reply With Quote
 
 
 
 
Marina
Guest
Posts: n/a
 
      21st Nov 2005
I don't think you should be allowing the primary key to change. If you want
to use a natural key, then you should not allow it to change once the row is
inserted. In theory you could then delete all the old rows and insert new
ones to mimic changing it. However, that is a lot of overhead.

Is there a reason you can't use a GUID or something like that as your
primary key?

"JustinMagaram" <(E-Mail Removed)> wrote in message
news:EB83C600-67E0-45DB-B972-(E-Mail Removed)...
> Suppose for a moment I am using "natural" keys and there are the two
> tables
> shown below.
>
> Country (countryName)
> LanguageSpokenInCountry (countryName, language)
>
> Suppose I set up cascade updates and deletes between the two tables, in
> both
> the dataset and database, so if a country is renamed, such as from
> "U.S.A."
> to "United States", the corresponding rows in LanguagesSpokenInCountry are
> updated.
>
> The default Update commmand for the child table looks something like this:
>
> UPDATE LanguageSpokenInCountry
> SET countryName = @countryName, language = @language
> WHERE ((countryName = @original_countryName) AND (language =
> @original_language))
>
> Now suppose someone modifies the dataset by changing the spelling of
> "U.S.A." to "United States" in the parent table, and changes a
> mis-spelling
> of "englsh" to "English" in the corresponding child table row. After the
> parent row is updated in the database, the update on the child row fails
> and
> generates a concurrency exception because by the time it gets executed
> there
> is no row in the child table where countryName = the @original_countryName
> of
> "U.S.A."
>
> Now suppose I try to fix this by changing the default Update command to
> the
> following command. Notice that now there WHERE clause looks for countries
> matching the current dataset country.
>
> UPDATE LanguageSpokenInCountry
> SET countryName = @countryName, language = @language
> WHERE ((countryName = @current_countryName) AND (language =
> @original_language))
>
> But this is only a partial fix. A problem remains in that whenever the
> parent row in the dataset changes, a cascade update in the dataset causes
> the
> child row to be marked as Modified, regardless of whether any other data
> in
> the child row besides the countryName foreign key has changed. As a
> result,
> the data adapter thinks it needs to run the Update command on the child
> row
> when no changes may be necessary. I suppose this could be fixed by
> pre-processing all "modified" child rows in the dataset before updating to
> look to see if any data actually changed besides the foreign key, and if
> not,
> simply accept the changes on the row. This seems like a hack to me.
>
> What is the recommend way to approach this overall problem?



 
Reply With Quote
 
luxspes
Guest
Posts: n/a
 
      22nd Nov 2005
What to stop careing about "how to save data in master
detail relationships in the proper order?" use an
object relational mapper (like http://www.nhibernate.org)


JustinMagaram wrote:
> Suppose for a moment I am using "natural" keys and there are the two tables
> shown below.
>
> Country (countryName)
> LanguageSpokenInCountry (countryName, language)
>
> Suppose I set up cascade updates and deletes between the two tables, in both
> the dataset and database, so if a country is renamed, such as from "U.S.A."
> to "United States", the corresponding rows in LanguagesSpokenInCountry are
> updated.
>
> The default Update commmand for the child table looks something like this:
>
> UPDATE LanguageSpokenInCountry
> SET countryName = @countryName, language = @language
> WHERE ((countryName = @original_countryName) AND (language =
> @original_language))
>
> Now suppose someone modifies the dataset by changing the spelling of
> "U.S.A." to "United States" in the parent table, and changes a mis-spelling
> of "englsh" to "English" in the corresponding child table row. After the
> parent row is updated in the database, the update on the child row fails and
> generates a concurrency exception because by the time it gets executed there
> is no row in the child table where countryName = the @original_countryName of
> "U.S.A."
>
> Now suppose I try to fix this by changing the default Update command to the
> following command. Notice that now there WHERE clause looks for countries
> matching the current dataset country.
>
> UPDATE LanguageSpokenInCountry
> SET countryName = @countryName, language = @language
> WHERE ((countryName = @current_countryName) AND (language =
> @original_language))
>
> But this is only a partial fix. A problem remains in that whenever the
> parent row in the dataset changes, a cascade update in the dataset causes the
> child row to be marked as Modified, regardless of whether any other data in
> the child row besides the countryName foreign key has changed. As a result,
> the data adapter thinks it needs to run the Update command on the child row
> when no changes may be necessary. I suppose this could be fixed by
> pre-processing all "modified" child rows in the dataset before updating to
> look to see if any data actually changed besides the foreign key, and if not,
> simply accept the changes on the row. This seems like a hack to me.
>
> What is the recommend way to approach this overall problem?

 
Reply With Quote
 
=?Utf-8?B?SnVzdGluTWFnYXJhbQ==?=
Guest
Posts: n/a
 
      22nd Nov 2005
I could use an identity field. I prefer having fewer columns if that will
work, identity columns add complexity on inserts since the new id must be
retrieved, and the textual name does uniquely identify the row. If someone
changes it they are likely keeping the identity constant but just changing
spelling.

"Marina" wrote:

> I don't think you should be allowing the primary key to change. If you want
> to use a natural key, then you should not allow it to change once the row is
> inserted. In theory you could then delete all the old rows and insert new
> ones to mimic changing it. However, that is a lot of overhead.
>
> Is there a reason you can't use a GUID or something like that as your
> primary key?
>
> "JustinMagaram" <(E-Mail Removed)> wrote in message
> news:EB83C600-67E0-45DB-B972-(E-Mail Removed)...
> > Suppose for a moment I am using "natural" keys and there are the two
> > tables
> > shown below.
> >
> > Country (countryName)
> > LanguageSpokenInCountry (countryName, language)
> >
> > Suppose I set up cascade updates and deletes between the two tables, in
> > both
> > the dataset and database, so if a country is renamed, such as from
> > "U.S.A."
> > to "United States", the corresponding rows in LanguagesSpokenInCountry are
> > updated.
> >
> > The default Update commmand for the child table looks something like this:
> >
> > UPDATE LanguageSpokenInCountry
> > SET countryName = @countryName, language = @language
> > WHERE ((countryName = @original_countryName) AND (language =
> > @original_language))
> >
> > Now suppose someone modifies the dataset by changing the spelling of
> > "U.S.A." to "United States" in the parent table, and changes a
> > mis-spelling
> > of "englsh" to "English" in the corresponding child table row. After the
> > parent row is updated in the database, the update on the child row fails
> > and
> > generates a concurrency exception because by the time it gets executed
> > there
> > is no row in the child table where countryName = the @original_countryName
> > of
> > "U.S.A."
> >
> > Now suppose I try to fix this by changing the default Update command to
> > the
> > following command. Notice that now there WHERE clause looks for countries
> > matching the current dataset country.
> >
> > UPDATE LanguageSpokenInCountry
> > SET countryName = @countryName, language = @language
> > WHERE ((countryName = @current_countryName) AND (language =
> > @original_language))
> >
> > But this is only a partial fix. A problem remains in that whenever the
> > parent row in the dataset changes, a cascade update in the dataset causes
> > the
> > child row to be marked as Modified, regardless of whether any other data
> > in
> > the child row besides the countryName foreign key has changed. As a
> > result,
> > the data adapter thinks it needs to run the Update command on the child
> > row
> > when no changes may be necessary. I suppose this could be fixed by
> > pre-processing all "modified" child rows in the dataset before updating to
> > look to see if any data actually changed besides the foreign key, and if
> > not,
> > simply accept the changes on the row. This seems like a hack to me.
> >
> > What is the recommend way to approach this overall problem?

>
>
>

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dataset and concurrency abcd Microsoft ADO .NET 1 24th Jun 2007 08:05 PM
Concurrency Violation in DataSet Update ADO.NET =?Utf-8?B?Tml5YXpp?= Microsoft Dot NET 2 27th Sep 2005 05:29 AM
primary key/xml/dataset issue. jack Microsoft ADO .NET 0 19th Jun 2004 04:50 AM
Concurrency Violation updating a DataSet =?Utf-8?B?QW5kcmVhIEdyYW5kaQ==?= Microsoft ADO .NET 3 26th May 2004 04:48 PM
Concurrency with DataSet & Command Object ElanKathir Microsoft ADO .NET 1 3rd Feb 2004 05:51 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 06:13 PM.