dポイントプレゼントキャンペーン実施中!

いつもお世話になっております。
VS2005 FrameWork2.0にて
ASPポストバックのDatasourceの挙動について質問させて下さい。

使用コントロールはDatasourceプロパティを持っていればなんでもいいのですが、例えばデザイナで、

DropDownList.DatasourceIdに SqlDatasourceを指定し、
SqlDatasourceのSelectQueryに" Select * from Table1 "
なんて指定しておけば、いくらポストバックが発生しても
常にDropDownList.DatasourceがNullでない状態で
、なおかつSQLサーバーをプロファイルしていても
Select文の発行は初回の1回だけでした。

でも、
手動で
DropDownList.DataSource = GetDataSource1()
DropDownList.DataBind()

※GetDataSource1()は、データベースをOpenしてDataTableを返すメソッド

みたいにコード上でバインドしておくと、
次のポストバック時にDataSourceがNULLになっています。

毎ポストバック時にDataBind()を書くと、
毎回Open~Select処理が走ってしまい嬉しくありません。

手動バインドさせる場合のスタンダードな書き方ってあるのでしょうか?

こういったことがナンセンスで、
本来は
[DataObjectMethod(DataObjectMethodType.Select)]属性をつけたメソッドを用意してObjectDatasourceのSelectメソッド等でやるのがスタンダードなんだよ
といったご指摘もあれば全てお聞きしたいと思っております。

よろしくお願い致します。

A 回答 (2件)

いくつかの条件がからんでいますが、一般的にということで。



ポストバック時、BindControlのDataSourceプロパティはnullになっていますが、通常、ViewStateをonにしていれば、BindControl自身の値(RepeaterであればItemTemplate生成のテキストボックスなど)がViewStateにドカンと保持されて、自動的に再表示されますので、再度DataBindする必要はないと思います。

自分は、ASP.NET 2.0 Web Formであれば、
初回時:データソースから読込み、DataBind実行
ポストバック時:追加・削除・更新の場合のみ、DB操作を行ってから読込み、DataBind実行
といった感じで統一しています。

ただ、毎回DBから読み込む方式と、ViewStateに値を埋めておいて送信する方法の比較ですが、DBドライバ側のキャッシュ機能などを考えれば、デカいViewStateより再SELECTのほうが早いような感じがします。

また、新しいASP.NET MVCではもはやViewStateもPostBackも使っていません(やっぱり)。
SQL DataSourceもObject DataSourceもキレイサッパリなくなって、「LINQかEntity Frameworkを使え」ということのようです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!
ASP.NET MVC については全く知りませんでした。
http://codezine.jp/article/detail/2748
の記事でも読んで勉強しておきます!

>ViewStateにドカンと保持されて、自動的に再表示されますので、再度DataBindする必要はないと思います。

ということですが、確かにコントロールそのももの値はViewStateに入ってるんですが、ドロップダウンリストのSelectedIndexに対応している列データが複数ほしい場合に困っていました。
例えば・・・
DataTextField = "Col1"
DataValueField = "Col2"
と設定していても、バインドデータの"Col3"まで保持できないといった場合です。
今回は、あまりバインドデータ量も多くないので
最初のPostBack時にDataTableをViewState("DataTable")に格納、
ドロップダウン["ddl_1"]のIndexChangedイベントにて、
ViewState("DataTable").Row(ddl_1.SelectedIndex).Item("Col3")
のようにアクセスするようにしました。

毎回Select投げるのが嫌だったのでViewStateに入れましたが、Htmlがでかくなるのもなぁ。。あとSessionに入れるのもなんだかなぁ。

ものは試しと、aspxファイルの.NET式でDataSource=" <% コードビハインドのメソッド %>"とやってもコンパイルエラーってどうしたらいいんだ・・・

という思いから質問を投稿した次第ですが、デザイナで宣言したときはViewStateに入っているのであれば、別にバッドプラクティスってわけじゃないんですね。少し安心しました。

重なりますが、ASP.NET MVCの補足まで入れていただいてありがとうございます。非常に為になりました!

お礼日時:2010/03/21 01:43

なるほど~ 複数のColumn値をDropdownListのSelectedIndexChangedイベントで拾いたいのですね。


おっしゃる通り。DataTableは更新スキームなどを持った、非常にデカいオブジェクトなので、SessionやViewStateに入れることは躊躇するところです。
this.コントロール名.SelectedValueで、選択値が拾えるので、あらかじめBindするCollectionに値を用意してしまうのがいいかもしれません。

ListItemCollection lcol = new ListItemCollection();
foreach (XXXRow row in XXXDataTable) {
ListItem litem = new ListItem(
row.Col1, row.Col2 + "|" + row.Col3);
lcol.Add(litem);
}
this.XXXDropDownList.DataSource = lcol;
this.XXXDropDownList.DataBind();

とすれば、イベントハンドラで"|"分割し、Col2とCol3が得られますね。
LINQtoSQLが使えれば、Col1と、Col2|Col3値連結のコレクションを取得して一発Bindできるんだけどなあ。
    • good
    • 0
この回答へのお礼

何度もご回答いただいてありがとうございます。
ValueFieldに連結して持たせるのはやったことがあるのですが、
意外と使いにくくて・・・

ともすれば
ユーザーコントロールを作ってしまって、連結されたValueFieldをCollectionとして返すプロパティを実装するとか・・・うう~ん。
「そもそもそんな設計にするなよー」てなもんなのかもしれません・・・

LINQtoSQLはまだ使った事ないんですよね・・・
早く使いたいもんです。

お礼日時:2010/03/26 13:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています