- - PR -
【ASP.NET C#】ソートしたデータセットが更新できない
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 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ステートメントは終了されました。" というものが表示されます。 ソートしたデータセットは更新できないのでしょうか? どなたかご教授いただけませんか。 | ||||||||||||
|
投稿日時: 2005-01-20 18:59
selectメソッドの戻り値をDatasouseに指定してます?
DataRowの配列だけど。 で、編集したときにDatasetに書き込むコードはどうなっています? | ||||||||||||
|
投稿日時: 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で、元のテーブルの行が取れますよ。
これは意味不明。私はセッションにDataTableを保存していますが、セッションが使えないならページのSaveViewStateメソッドをオーバーライドして、ここでDataTableをViewStateに書き出してやる、という方法もあります。もちろん、LoadViewStateもオーバーライドして、取り出す必要があります。 _________________ | ||||||||||||
|
投稿日時: 2005-01-21 09:37
Linさん、Jittaさんありがとうございます!!
これはデータグリッドをカスタムしたコントロールを使用しており データセットを保持するプロパティを追加したためです。
おっしゃるとおりでした。 原因はDataTableをselectすると参照やらなにやらがあるみたいで うまくいかず、.Copyを使って一旦参照を切ってコピーし その後addし直す強引な方法を取っていた為 参照が切れて各行のInsertになっていたのだと思われます。 この方法は考え直します。 セッションならDataset保存したりソートした後のDataViewを保持できる ようなのですが、カスタムにしてプロパティにしてしまっている為 DataViewを保持できませんでした。プロパティはDataset型にしています。 これをどうにかする必要がありそうです。 object型にしてやればいいのでしょうか?
DataViewになると取得方法かわるんですね? ちょっとDataViewは無知で観点がずれていたらすいません。 ソート前とソート後で取得方法が変えるようにするのでしょうか? 引き続きご教授いただければしあわせです。 | ||||||||||||
|
投稿日時: 2005-01-21 10:00
ちょっと自分で整理して考えてみたのですが
DataView型がDataTable型にキャストできれば 解決はしそうなのですが、それって不可能ですか? 保持するデータはDatasetとして持ちたいという点があるので dataViewでソートした後 grid.DataSource = dataView; のあとに 保持するデータにこのdataViewをDataTable型に 戻したやつをいれられれば解決しそうなのです。 DataViewについてみているとどうも DataSetやDataTableと 別のもので考えたほうがいい というような情報もみかけたので 無理を言っているのかもしれませんが。。。 ソートと更新の併用の情報など この方法以外でもよい方法がありましたら お教えいただけますでしょうか よろしくお願いします。 | ||||||||||||
|
投稿日時: 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というプロパティがあるのですが、それは調べた上でのことですよね? _________________ | ||||||||||||
|
投稿日時: 2005-01-24 10:58
Jittaさん返答有難うございます。
dataview.TableでDataTableを取得できるのは 確認済でしたが、ソート前の情報を取得するようでしたので 使用していませんでした。
いえ、正直完全に弊害を理解しての上ではありませんでした^^; ただカスタムのデータグリッドをつくりまったく別のDatasetを保持する プロパティを作ってあるだけです。DataSouceとの関連性はありません。 Viewでソートした場合はDataView(index).Rowで取得するのは できたのですが、これをうまく活用する方法がわかりませんでした。 SessionでDatasetを保持する場合で考えると。 まず最初にBIND時にはSessionにDataset型をいれて ソートしたときにはDataView型を入れるというかたちでしょうか? でもViewはあくまでViewだから違うのか。。。。 はじめからデータをDataView型でバインドするんでしょうか? すいませんちょっとわかっていない模様です。 このへんの更新とソートを同時に行っている情報のありかなど ご存知でしたらお教えいただけませんでしょうか? いろいろ調べてもソートと更新は別で記述されている ページしか見つけられませんでした;; ご教授いただけたら幸いです。 | ||||||||||||
|
投稿日時: 2005-01-24 14:45
この方法で解決しそうです。 やっとDataViewがわかってきました。 ありがとうございました。 |