こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ASP.NET:複数結合テーブルのデータ変更方法について

ASP.NET:複数結合テーブルのデータ変更方法について
こんにちは。
現在Visual Studio2008(ASP.NET、ADO.NET) +SQL Server2005 Stdの環境でデータベースを参照したWebアプリケーションを作成しています。

GridViewを使い、データベースの内容を表示し、修正や追加、削除を行いたいと思っています。
(SQLのUpdate,Insert,Deleteに該当)

主キーが設定された単独のテーブルに対しては、GridView内のデータソースでデータベースを選び、
該当のテーブルを選択。その後「INSERT,UPDATEおよびDELETEステートメントの作成」オプションを選ぶことでこれらの変更方法が簡単に実装できるのを確認しております。

しかし、主キー外部キーの関係を持つ2つ以上のテーブルを結合したものに関してこれらの変更を行う場合は通常どのようにするのでしょうか。
何かヒントになるキーワードや参考になるコードを教えていただけないでしょうか?

単独のテーブルの時と同じく、結合したテーブルデータ(ビューに該当)をGridViewに表示し、そのGridView上で変更を行いたいと思っています。

SQL Server側でこれらのテーブルを結合したViewを作成し、これを選ぶことでGridViewに表示する事が可能なのは確認したのですが、やはり「INSERT,UPDATEおよびDELETEステートメントの作成」オプションは選択できませんでした。


以上よろしくお願いいたします。

投稿日時 - 2010-05-07 11:37:09

QNo.5877566

困ってます

質問者が選んだベストアンサー

正規化データベースの結合テーブルを簡単・安全に一括更新することは、我々システムエンジニアにとって永遠のテーマであり、運用ニーズやパフォーマンスの点でさまざまな妥協にもとづき、わざと冗長化するなど、現実解に則って実装することが多いです。
ただ最近、Microsoftは、コンセプト、ツールの両面でこの問題に真正面から取り組んでおり、めざましく進歩しています。

一般的に、ASP.NETでデータベースアクセスするには、いくつかの方法があります。
原始的な(古い)方法から順に述べますと、
・DataConnection/DataCommandによるアクセス(SQL直書き)
・DataAdapter/DataSourceによるアクセス
・TableAdapter/DataTableによるアクセス
・SQLDataSourceによるアクセス
・ObjectDataSourceによるアクセス
・LINQ for SQLによるアクセス
・Entituy Frameworkによるアクセス
・その他、サードパーティー製品による複合的なアクセス
です。また、これ以外には別解として、ストアドプロシージャを定義し、各スキームから呼び出す方法もあります。
このうち、ご希望の「正規化されたデータベース」へ、結合テーブルのまま、SQLを書かずに更新するスキームは、最後の3つです。

おそらくご使用になっているスキームは、GridViewと同時期に発表されたSQLDataSourceだと思われますが、これは簡略なDBハンドリングをSQLレスで実現するために考えられたもので、結合テーブル更新は難しいです(デザイナの更新メソッドを全部オーバーライドすればもちろん可能ですが、それなら最初からSQLDataSOurceなど使わないでしょう)
ObjectDataSource以前のスキームなら順次、個別更新するしかありません。

LINQ以降であれば、結合エンティティのまま正規化されたDBを更新できます。
ComponentOneなど、サードパーティ製の市販グリッドは、内部でデータアクセスモジュールを自動生成するので、LINQを使わなくても一括更新は可能です。

ただ現実の仕事では、それ以外の要素として悲観同時処理や長時間ロック、トランザクションなどが複雑になることがあるので、全部ストアドプロシージャに持ち込んでしまいます。

簡単な社内システムや、僅少アクセスの閲覧中心なWebシステムでしたら、LINQ for SQLでいけると思います。
いずれにせよ、SQLDataSourceなど使っていては拡張性も乏しく、先は見えています。

参考URL:http://chicasharp.net/scottgu/result2.aspx?target=LINQ+to+SQL+%28%E3%83%91%E3%83%BC%E3%83%88+1+-+LINQ+to+SQL%E3%82%92%E4

投稿日時 - 2010-05-10 19:46:45

お礼

ご回答いただきありがとうございます。

>正規化データベースの結合テーブルを簡単・安全に一括更新することは、我々システムエンジニアにとって永遠のテーマであり、運用ニーズやパフォーマンスの点でさまざまな妥協にもとづき、わざと冗長化するなど、現実解に則って実装することが多いです。

やはりそうなのですね。単テーブルしか扱った事がなかったので参考になります。


>・DataConnection/DataCommandによるアクセス(SQL直書き)
>・DataAdapter/DataSourceによるアクセス
>・TableAdapter/DataTableによるアクセス
>・SQLDataSourceによるアクセス
>・ObjectDataSourceによるアクセス
>・LINQ for SQLによるアクセス
>・Entituy Frameworkによるアクセス

ご察しの通りSQL Data Sourceをよく利用させていただいております。けれどこれは複雑なテーブルに対してあまり使えないのですね。
,LINQ to SQL,Entity Frameworkに関しましてはまだ扱った事がなくこれから勉強しようと思います。

ObjectDataSourceも例でしか見た事がなく使った事がなかったのですが、例えば正規化されたA,Bというテーブルを結合しておいてGridViewの編集機能から一度にUpdateする時はその呼び出されるUpdate関数の中でupdate文をA,Bに対してそれぞれ行う(つまり2回)イメージで正しいでしょうか?

>ただ現実の仕事では、それ以外の要素として悲観同時処理や長時間ロック、トランザクションなどが複雑になることがあるので、全部ストアドプロシージャに持ち込んでしまいます。

なるほどそういった事まで気が回っていなかったです。ストアドプロシージャについても調べてみます。

投稿日時 - 2010-05-12 20:32:23

ANo.3

このQ&Aは役に立ちましたか?

12人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

GridViewはSQL DataSourceやObject DataSourceど同世代のサーバコントロールなので、これらと相性がいいといえばいいです。
今回のお話は、GridViewからの結合テーブル一括更新なので、おっしゃるとおり、Object DataSourceのUpdate定義から、カスタムメソッドを呼び出し、その中で更新用のDataTableデータ(やDataRow)を生成して、TableAdapter.Update()で順次更新していくことになります。
Object DataSourceは更新時、BindされているGridViewテンプレート内の入力サーバコントロールと同一プロパティ名を持っ、データコンテナオブジェクトを勝手に生成するので、その中の値を順次、DataRowなどに移していく必要があります。
面倒ですが、ObjectDataSource使う場合のキモなので、頑張って実現してください。

投稿日時 - 2010-05-17 16:23:28

お礼

見通しが立ちました。
実戦で試してみたいと思います。

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

投稿日時 - 2010-05-19 11:54:51

ANo.2

>テーブルのメンテナンスは分割されているテーブル毎にやるのが一般的でしょうか?
GridViewへの表示は、別にSQL文により結合された状態でもよいと思いますよ。

更新ロジックを、しっかり自身で書き上げれば問題なく通ると思います。
その発行単位が個別になるかどうかは、SQLの書き方にもよってくると思いますが、、、


もっと情報を公開できませんか?

ASP.NETがC#/VBのどっちで構成されているのかもわかりません。

特に知りたいのは
[画面.aspx]
<asp:GridView>
この中身がどうなっているか
</asp:GridView>

<asp:SqlDataSource>
知りたいのはSelectCommandの内容
ビハインドコードで指定している場合は、ここでは不要
</asp:SqlDataSource>


それと[画面.aspx.vb(VB)]か[画面.aspx.cs(C#)]のどっちかで、GridView絡みの部分



抜粋で結構ですが、公開する情報量が多いほど、参考となるサイトや、簡単なサンプルを提供できると思います。

投稿日時 - 2010-05-10 11:17:54

お礼

>ASP.NETがC#/VBのどっちで構成されているのかもわかりません。
C#を考えています。

>抜粋で結構ですが、公開する情報量が多いほど、参考となるサイトや、簡単なサンプルを提供できると思います。

すいません。あまりデータベースアプリケーション作成のスキルがない事もあり、実物はまだ設計段階でして具体例お出しできない状態です。
一般的に、正規化により分割されている(しかし表示上結合する必要のある)テーブルの扱いをどうすればよいのかわからない為質問させていただきました。
(表示はわかるのですが、更新追加などのメンテナンス部分。)

もう少し形が見えてきましたら質問させていただきたく思います。

ご回答いただきありがとうございました。

投稿日時 - 2010-05-12 20:15:38

ANo.1

>ADO.NET
内部でUpdate,Insert,Deleteの時に発行しているのは、SQLサーバへのSQL文です。

「SQL Server Management Studio」で発行できないSQL文はもちろん通りません。

結合した時点でキーを失った場合、TableというよりViewです。
「読み取り専用」となっていると思った方が良いです。

・結合するテーブルA・Bの構造とKeyと取得SQL文
・GridViewへのデータソースの設定方法
などが公開されていれば、もっと詳細なアドバイスができると思いますが、今の方法では「無理です」としか言えません。

投稿日時 - 2010-05-07 16:32:57

補足

ご回答いただきありがとうございます。

>「読み取り専用」となっていると思った方が良いです。
やはりそうですよね。


>・結合するテーブルA・Bの構造とKeyと取得SQL文
>・GridViewへのデータソースの設定方法

テーブルに関してはまだ考えている途中ですが2つの場合を考えています。
(1)正規化により分割されたテーブル(SQL servernoサンプルテーブルのNorthwindのようなテーブル)の結合
(2)元のテーブルとそのテーブル仕様変更などで項目を追加する為のテーブル(主キーは同じ)の結合
((2)は分割して管理するのではなくて元のテーブル側に項目を追加する(元のテーブルを変更(追加)する)のがきっと普通なのでしょうね。そうすればテーブルひとつで済みますし。)

どちらもユーザーに見せる場合テーブル結合した状態でGridViewを使い見せたいと思っています。
そしてメンテナンス(追加、削除、更新)する時もその結合した状態でのGridViewを使えたら良いなと考えていました。(1つのテーブルの時は実現できています。)

こういう場合、テーブルのメンテナンスは分割されているテーブル毎にやるのが一般的でしょうか?
(メンテナンス画面はテーブル毎に作成)


データソースの設定はGridViewのタスク→新しいデータソース→データベース→(該当のデータベース(SQL Serverのテーブル)選択)で設定しています。

投稿日時 - 2010-05-09 17:52:06

あなたにオススメの質問