- PR -

【ASP.NET C#】ソートしたデータセットが更新できない

投稿者投稿内容
PoH
常連さん
会議室デビュー日: 2003/09/09
投稿数: 48
投稿日時: 2005-01-20 17:24
WEBフォーム C#で作成しています。

ソート機能と更新機能を両方もつグリッドを作成しています。
更新は各行で編集、削除を行い、別に用意した一括更新ボタンで
更新を行っています。

グリッドにバインド時DatasetはViewstateに保持
ソート時は保持しているDatasetを
DataSet.Tables[テーブル名].Selectを使用してソートし
そのをbindし直しています。

更新時はこの保持しているDatasetを
.Update(Dataset)で更新をかけています。

ソートを使用せずページングのみで変更を行うと
正しく変更されるのですが
ソートしたデータを更新ができません。

Dataviewのソートを使用していないのは、
ソート後、各行の編集ボタンを押すとソート前の行の値を更新してしまうためと
DataView型はViewStateで保持しているDataset型のところに
保持できない為もあり使用していません。

ちなみに.Update(Dataset)のところで落ちるのですが

エラーメッセージは

"PRIMARY KEY 違反、制約 'PK_TABLE_TEST': オブジェクト
'TABLE_TEST' には重複したキーは挿入できません。
\r\nステートメントは終了されました。"

というものが表示されます。

ソートしたデータセットは更新できないのでしょうか?

どなたかご教授いただけませんか。
Lin
ベテラン
会議室デビュー日: 2004/11/08
投稿数: 50
投稿日時: 2005-01-20 18:59
selectメソッドの戻り値をDatasouseに指定してます?
DataRowの配列だけど。
で、編集したときにDatasetに書き込むコードはどうなっています?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-01-20 22:09
 ん〜?DataTable.Selectメソッドでソート?もしかして、そうやって取り出したDataRowを、Duplicateして別のDataTableに入れ直しているとか?だとしたら、RowStateがAddedになって、Updateメソッドを実行するとInsertCommandが実行され、重複追加になるね。DataAdapterのUpdateメソッドは、各行のRowStateを見て、Insert, Update, Deleteの処理を振り分けます。なので、これが変更されるような操作は禁止です。

 DataViewの行と、DataGridの行は対応が取れていますよね。なので、DataView.Item(index).Rowで、元のテーブルの行が取れますよ。

引用:

DataView型はViewStateで保持しているDataset型のところに保持できない為もあり使用していません。


これは意味不明。私はセッションにDataTableを保存していますが、セッションが使えないならページのSaveViewStateメソッドをオーバーライドして、ここでDataTableをViewStateに書き出してやる、という方法もあります。もちろん、LoadViewStateもオーバーライドして、取り出す必要があります。

_________________
PoH
常連さん
会議室デビュー日: 2003/09/09
投稿数: 48
投稿日時: 2005-01-21 09:37
Linさん、Jittaさんありがとうございます!!

引用:
DataView型はViewStateで保持しているDataset型のところに保持できない為もあり使用していません。


これはデータグリッドをカスタムしたコントロールを使用しており
データセットを保持するプロパティを追加したためです。

引用:
ん〜?DataTable.Selectメソッドでソート?もしかして、そうやって取り出したDataRowを、Duplicateして別のDataTableに入れ直しているとか?だとしたら、 RowStateがAddedになって、Updateメソッドを実行するとInsertCommandが実行され、重複追加になるね。 DataAdapterのUpdateメソッドは、各行のRowStateを見て、Insert, Update, Deleteの処理を振り分けます。なので、これが変更されるような操作は禁止です。


おっしゃるとおりでした。
原因はDataTableをselectすると参照やらなにやらがあるみたいで
うまくいかず、.Copyを使って一旦参照を切ってコピーし
その後addし直す強引な方法を取っていた為
参照が切れて各行のInsertになっていたのだと思われます。
この方法は考え直します。

セッションならDataset保存したりソートした後のDataViewを保持できる
ようなのですが、カスタムにしてプロパティにしてしまっている為
DataViewを保持できませんでした。プロパティはDataset型にしています。
これをどうにかする必要がありそうです。
object型にしてやればいいのでしょうか?

引用:
DataViewの行と、DataGridの行は対応が取れていますよね。なので、DataView.Item(index).Rowで、元のテーブルの行が取れますよ。


DataViewになると取得方法かわるんですね?
ちょっとDataViewは無知で観点がずれていたらすいません。
ソート前とソート後で取得方法が変えるようにするのでしょうか?

引き続きご教授いただければしあわせです。
PoH
常連さん
会議室デビュー日: 2003/09/09
投稿数: 48
投稿日時: 2005-01-21 10:00
ちょっと自分で整理して考えてみたのですが
DataView型がDataTable型にキャストできれば
解決はしそうなのですが、それって不可能ですか?

保持するデータはDatasetとして持ちたいという点があるので
dataViewでソートした後
grid.DataSource = dataView;
のあとに
保持するデータにこのdataViewをDataTable型に
戻したやつをいれられれば解決しそうなのです。

DataViewについてみているとどうも
DataSetやDataTableと
別のもので考えたほうがいい
というような情報もみかけたので
無理を言っているのかもしれませんが。。。

ソートと更新の併用の情報など
この方法以外でもよい方法がありましたら
お教えいただけますでしょうか

よろしくお願いします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-01-21 22:30
 むむむ?
 Viewは、あくまでもViewです。見方、見せ方の一つにすぎません。

 DataTableをバインドした場合、グリッドの行とテーブルの行は一致します。ただし、グリッドをページングしたときは、ページ番号だけ下駄を履かせる必要があります。同じように、DataViewをバインドした場合、グリッドの行とビューの行は一致します。グリッドとビューの行は一致していますから、何でソートしようが、グリッドの1番目はビューの1番目、グリッドの10番目はビューの10番目です。DataView(index)で取得できます。これは変わりません。
 次にビューですが、あくまでビューです。見せ方を変更するにすぎません。見せ方だけ変えるので、データは複製していません。データは持っていないので、元のデータを参照できなければなりません。それがDataRowView.Rowプロパティです。ソートの条件によってDataView(index).Rowが指すものは変わりますが、見せようとしている「index番目のデータ」が取り出せます。

 もしかして、DataGridのDataSourceに指定されているオブジェクトをシリアライズしてViewStateに格納ですか?!まぁ、DataViewはシリアライズ可能とマークされていませんからね。。。う〜ん、ViewStateの弊害は理解の上、なんですよね?

> DataView型がDataTable型にキャストできれば
> 解決はしそうなのですが、それって不可能ですか?
DataViewのメンバにTableというプロパティがあるのですが、それは調べた上でのことですよね?

_________________
PoH
常連さん
会議室デビュー日: 2003/09/09
投稿数: 48
投稿日時: 2005-01-24 10:58
Jittaさん返答有難うございます。

引用:
DataViewのメンバにTableというプロパティがあるのですが、それは調べた上でのことですよね?


dataview.TableでDataTableを取得できるのは
確認済でしたが、ソート前の情報を取得するようでしたので
使用していませんでした。

引用:
もしかして、DataGridのDataSource に指定されているオブジェクトをシリアライズしてViewStateに格納ですか?!まぁ、DataViewはシリアライズ可能とマークされていませんからね。。。う〜ん、ViewStateの弊害は理解の上、なんですよね?


いえ、正直完全に弊害を理解しての上ではありませんでした^^;
ただカスタムのデータグリッドをつくりまったく別のDatasetを保持する
プロパティを作ってあるだけです。DataSouceとの関連性はありません。

Viewでソートした場合はDataView(index).Rowで取得するのは
できたのですが、これをうまく活用する方法がわかりませんでした。

SessionでDatasetを保持する場合で考えると。
まず最初にBIND時にはSessionにDataset型をいれて
ソートしたときにはDataView型を入れるというかたちでしょうか?
でもViewはあくまでViewだから違うのか。。。。
はじめからデータをDataView型でバインドするんでしょうか?
すいませんちょっとわかっていない模様です。

このへんの更新とソートを同時に行っている情報のありかなど
ご存知でしたらお教えいただけませんでしょうか?

いろいろ調べてもソートと更新は別で記述されている
ページしか見つけられませんでした;;

ご教授いただけたら幸いです。
PoH
常連さん
会議室デビュー日: 2003/09/09
投稿数: 48
投稿日時: 2005-01-24 14:45
引用:
DataViewをバインドした場合、・・・・


この方法で解決しそうです。

やっとDataViewがわかってきました。

ありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)