none
ListViewとObjectDataSourceを使ったページングで動的SQLを使いたい RRS feed

  • 質問

  • 現在SQL Serverからデータを検索してページング可能な表を作成しているのですが、

    検索条件が動的に変わる場合について、どのように実装すべきか悩んでいます。

     

    環境はVS 2008 Pro 言語はC#、DBはSQL Server 2005です。

     

    具体的には、データ件数が多いので全取得を行わないrow_number()関数を使ってページングを行いたく、

    ObjectDataSourceとDataSetを使ってListViewにBindするところまでは出来たのですが、加えて検索条件が

    動的に変わるので(例えば、苗字と名前を両方指定して検索、またはそのどちらかを指定するようなもので)

    Where句を動的に書き換える必要があると考えています。

     

    動的なSQLを書く場合、DataSetの内のTableAdapter#CommandTextのSelect文を変更出来れば良いのですが

    その方法が見つけられず。。。

    また、セキュリティの観点から、可能であればパラメータクエリを使用したいと考えています。

    この場合、ストアドを作成しその中でT-SQLで行わなければならないでしょうか。

    しかし、ストアドでsp_executesqlを使って動的にパラメータを含むSQL文を作る事も難しいなと。。。

     

    皆様はページングを行い、且、動的なWhere句を書かなければならないような場合、どのように実装していますでしょうか。

    検索していたら、2年以上前にも同様な話題があり、ObjectDataSource->DataSet->TableAdapterとオブジェクトを

    たどれれば良かったのですか見つけられませんでした。

    http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-41426.htm

     

    また、ListViewは.Net3.0から導入されたようですが、DataList等の枯れた物を使う事の方が

    現状では多いでしょうか。ネットを検索しているとListViewは高機能なように感じたので使用してみた

    しだいです。

     

    宜しくお願い致します。

     

    2008年10月6日 13:49

回答

  • App_Code フォルダにデータセット(.xsd ファイル)を作ったのですよね?

     

    とすると DataSet と TableAdapter クラスが自動生成されて、以下のフォルダ
    の下の Web サイト名のフォルダの奥深くにあるはずです。

     

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

     

    その TableAdapter クラスを見ると partial になっているのが分かると思いま
    す。

     

    そこで、ウィザードで定義できないクエリ(今回のように WHERE 句の条件が動
    的に変化するようなクエリ)は、新たに App_Code フォルダに手作業で拡張コー
    ドを記述して、ウィザードで作った partial クラスに合体させることができます。

     

    その方法で、お望みの処置が可能になると思います。

     

    拡張コードは、例えば、以下のような感じになります。

     

    Code Snippet

    namespace AuthersDataSetTableAdapters
    {
        public partial class authorsTableAdapter
        {
             [DataObjectMethod(DataObjectMethodType.Select)]
             public AuthersDataSet.authorsDataTable GetDataByTop(int n)
             {
                 string query = String.Format("SELECT TOP {0} * FROM authors", n);
                 SqlDataAdapter sqlda = new SqlDataAdapter(query, this.Connection);
                 AuthersDataSet.authorsDataTable table = new AuthersDataSet.authorsDataTable();
                 sqlda.Fill(table);
                 return table;
             }
         }

    }

     

    2008年10月6日 14:44
  •  タク2007 さんからの引用

    動的なSQLを書く場合、DataSetの内のTableAdapter#CommandTextのSelect文を変更出来れば良いのですが
    また、セキュリティの観点から、可能であればパラメータクエリを使用したいと考えています。

    この場合、ストアドを作成しその中でT-SQLで行わなければならないでしょうか。

    しかし、ストアドでsp_executesqlを使って動的にパラメータを含むSQL文を作る事も難しいなと。。。

     

    SurferOnWwwさんが書かれている方法でTableAdaperにメソッドを追加して、そのメソッド内でパラメータライズドクエリを組み立てるか、もしくはタク2007さんが書かれているように、ストアドプロシージャ内で動的にSQL文を作成し、sp_executesqlを用いて発行する方法になるでしょう。パラメータライズドクエリやsp_executesqlを使うことは、セキュリティの観点から非常に重要なことです。
    私はほとんどの場合、ストアドプロシージャで作成します。理由は、Windowsフォームアプリケーションなどからでも使用できますし、また、ASP.NETがバージョンアップして仕様が変更になった際でも、ストアドプロシージャを呼ぶロジックを変えるだけで対応できるであろうからです。

     

     タク2007 さんからの引用

    また、ListViewは.Net3.0から導入されたようですが、DataList等の枯れた物を使う事の方が

    現状では多いでしょうか。ネットを検索しているとListViewは高機能なように感じたので使用してみた

    しだいです。


    ListViewを使って全然いいと思います。もちろん、バグが無いということを私が保証できるはずもありませんので責任は持てません。しかし、ASP.NETが世の中に出てきてから何年も経ちますし、そのテクノロジーにおけるコントロールの一つですので、全く新しいものというわけではなく、十分なテストもされているでしょうから、それほど使用をためらう対象ではないんじゃないかと個人的には思います。

    2008年10月6日 15:49
    モデレータ

すべての返信

  • App_Code フォルダにデータセット(.xsd ファイル)を作ったのですよね?

     

    とすると DataSet と TableAdapter クラスが自動生成されて、以下のフォルダ
    の下の Web サイト名のフォルダの奥深くにあるはずです。

     

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

     

    その TableAdapter クラスを見ると partial になっているのが分かると思いま
    す。

     

    そこで、ウィザードで定義できないクエリ(今回のように WHERE 句の条件が動
    的に変化するようなクエリ)は、新たに App_Code フォルダに手作業で拡張コー
    ドを記述して、ウィザードで作った partial クラスに合体させることができます。

     

    その方法で、お望みの処置が可能になると思います。

     

    拡張コードは、例えば、以下のような感じになります。

     

    Code Snippet

    namespace AuthersDataSetTableAdapters
    {
        public partial class authorsTableAdapter
        {
             [DataObjectMethod(DataObjectMethodType.Select)]
             public AuthersDataSet.authorsDataTable GetDataByTop(int n)
             {
                 string query = String.Format("SELECT TOP {0} * FROM authors", n);
                 SqlDataAdapter sqlda = new SqlDataAdapter(query, this.Connection);
                 AuthersDataSet.authorsDataTable table = new AuthersDataSet.authorsDataTable();
                 sqlda.Fill(table);
                 return table;
             }
         }

    }

     

    2008年10月6日 14:44
  •  タク2007 さんからの引用

    動的なSQLを書く場合、DataSetの内のTableAdapter#CommandTextのSelect文を変更出来れば良いのですが
    また、セキュリティの観点から、可能であればパラメータクエリを使用したいと考えています。

    この場合、ストアドを作成しその中でT-SQLで行わなければならないでしょうか。

    しかし、ストアドでsp_executesqlを使って動的にパラメータを含むSQL文を作る事も難しいなと。。。

     

    SurferOnWwwさんが書かれている方法でTableAdaperにメソッドを追加して、そのメソッド内でパラメータライズドクエリを組み立てるか、もしくはタク2007さんが書かれているように、ストアドプロシージャ内で動的にSQL文を作成し、sp_executesqlを用いて発行する方法になるでしょう。パラメータライズドクエリやsp_executesqlを使うことは、セキュリティの観点から非常に重要なことです。
    私はほとんどの場合、ストアドプロシージャで作成します。理由は、Windowsフォームアプリケーションなどからでも使用できますし、また、ASP.NETがバージョンアップして仕様が変更になった際でも、ストアドプロシージャを呼ぶロジックを変えるだけで対応できるであろうからです。

     

     タク2007 さんからの引用

    また、ListViewは.Net3.0から導入されたようですが、DataList等の枯れた物を使う事の方が

    現状では多いでしょうか。ネットを検索しているとListViewは高機能なように感じたので使用してみた

    しだいです。


    ListViewを使って全然いいと思います。もちろん、バグが無いということを私が保証できるはずもありませんので責任は持てません。しかし、ASP.NETが世の中に出てきてから何年も経ちますし、そのテクノロジーにおけるコントロールの一つですので、全く新しいものというわけではなく、十分なテストもされているでしょうから、それほど使用をためらう対象ではないんじゃないかと個人的には思います。

    2008年10月6日 15:49
    モデレータ
  • SurferOnWwwさんご回答有難う御座います。

    大変参考になりました。

     

    >App_Code フォルダにデータセット(.xsd ファイル)を作ったのですよね?

    はい。データセットは、ここに入れています。

     

    # 1点、つまずいたところがあるので、記述させて頂きます。

    自動生成されたAdapterクラスもusingの記述が一つもないので、partialで追加するクラス

    も不要かと思ったのですが、実行時コンパイル(App_Codeフォルダなので)で怒られました。

     

    で、下記を追加したところうまく行きました。有難う御座います。

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.ComponentModel;

     

    ただ、App_Codeは動的生成したコードなどを入れておく特別なフォルダだと

    思うので、自ら作成したクラスは入れたくないなと、勝手に考えていますがどうなんでしょ。

    ビルドアクションにコンパイルを指定すれば大差はないので、解は無いのでしょうけど。

     

    2008年10月7日 6:28
  • trapemiyaさん ご回答、有難う御座います。

     

    やはりストアドを使われる場合もあるのですね。

     

    >ListViewを使って全然いいと思います。

    そうですよね。私もページングやデザインが綺麗に分離できていて

    良く出来ているなーと思っています。

     

    ストアドも当方の未熟さゆえに、難しそうだなーと思っていたのですが

    実際書いてみると、動的パラメータも実現できました。

     

    # sp_executesqlを使う場合、第2、第3引数にパラメータを列挙しますが

    # 第1引数のSQL文に使用しない変数を記述しても良い事を知らなかったので

    # SQL文が動的に変わったら、第2、第3引数も合わせて変えなければならいと思っていました(苦笑

     

    とりあえず今回は巨大なSQLになりそうであれば、ストアドで実装し

    プログラムで文字列操作した方が楽な場合はAdapterクラスを拡張する方針で

    実装しようと思います。

     

    有難う御座いました。

     

    2008年10月7日 6:43
  •  タク2007 さんからの引用

    ただ、App_Codeは動的生成したコードなどを入れておく特別なフォルダだと

    思うので、自ら作成したクラスは入れたくないなと、勝手に考えていますがどうなんでしょ。

     

    新しい項目の追加でクラスを追加してみてください。
    必ずApp_Codeの下に作られるはずです。

    WebサイトプロジェクトではクラスのソースコードはApp_Codeの下に置かないといけませんが、それはウィザード等で作成されるコードに限りません。

    安心して使ってください。

    2008年10月7日 7:32
  • どっとねっとふぁんさん ご回答有難う御座います。

     

    ビジネスロジックのクラスなどはaspx関連のクラスとは別に切り出して作っていますが

    App_Codeの配下には一つも入れていないです。

    もしかしてこれって、あまり一般的ではないのでしょうか。

     

    理由は上記に書いたようにApp_Codeは動的生成したコードなどを入れておき

    動作直前にコンパイルされる(させたい)と理解しているからです

    (間違っていたら、是非ご指摘頂けたらと思います)。

     

    App_Codeに入れなければ動作前にコンパイルされdllとしてbinフォルダに配置されるので

    コードの共通化は当然可能であり、今のところ動作も問題無いようです。

    2008年10月7日 10:35
  • http://dotnetfan.org/blogs/dotnetfanblog/archive/2008/01/21/2717.aspx

    この2つの違いを私が理解していなかったので(お伝えもしていなかった)ので

    変な質問をしてしまったようです。

     

    私はWebアプリケーションで作成しているのでApp_Codeに入れる事は

    珍しいのでは?と疑問に思ったしだいです。

     

    それを踏まえて、DataSetクラスとそのpartialクラスはWebアプリケーションであっても

    App_Codeに入れるのが、決まりなのでしょうか。

    という質問になります。

     

    度々、申し訳ありません。

    2008年10月7日 11:10
  • もしかして、Webアプリケーションプロジェクトを利用されていますか?
    その場合、クラスはどこにおいてもかまいません。

     

    なお、Webアプリケーションプロジェクトを利用されている場合は、すべてのソースコード(aspxをのぞく)は事前にコンパイル/dll化されbinフォルダに配置されると思います。
    App_Codeの配下に作成したクラスもdll化されていませんか?

     

    #そういや、WebアプリケーションプロジェクトでApp_Code配下のクラスの動きを確認したことはなかったか。。。

     

    2008年10月7日 11:11
  •  タク2007 さんからの引用

    ただ、App_Codeは動的生成したコードなどを入れておく特別なフォルダだと

    思うので、自ら作成したクラスは入れたくないなと、勝手に考えていますがどうなんでしょ。

    ビルドアクションにコンパイルを指定すれば大差はないので、解は無いのでしょうけど。

     

    「解」は App_Code フォルダに入れることだと思います。もともと、その目
    的で App_Code フォルダが用意されているそうですから。

     

    ASP.NET Web サイト内の共有コード フォルダ
    http://msdn.microsoft.com/ja-jp/library/t990ks23(VS.80).aspx

     

    "ページ間で共有するコードが Web アプリケーションに含まれている場合は、
    Web アプリケーションのルートの下にある 2 つの特殊フォルダ (Bin フォル
    ダおよび App_Code フォルダ) のいずれかでコードを保持できます。"

     

    アプリケーション内で利用する共通のクラスを作成する方法
    http://msdn.microsoft.com/ja-jp/library/cc719212.aspx

     

    "アプリケーション内の各ページで共通して利用するルーチンは、クラスとし
    て 1 箇所にまとめておくと便利です。ASP.NET 2.0 は、このような用途のた
    めに App_Code フォルダという特別なフォルダを用意しています。"


    多分ほとんどの人はそうしているのではないかと思います。特に、自分のよ
    うな VWD2005/2008 Express Edition(「Web アプリケーション」がテンプ
    レートに無いのです)ユーザーは、共有コードを App_Code フォルダ以外に
    置くということは、全くの考えの外なんです。(笑)

    2008年10月8日 12:31
  •  タク2007 さんからの引用

    とりあえず今回は巨大なSQLになりそうであれば、ストアドで実装し

    プログラムで文字列操作した方が楽な場合はAdapterクラスを拡張する方針で

    実装しようと思います。

     

    ROW_NUMBER() を使ったようなページングを考えると、ObjectDataSource
    標準のページング用のメソッドを、TableAdapter クラスを拡張して実装
    した方が楽だと思います。

     

    以下のサイトを参照ください。

     

    ObjectDataSource.EnablePaging プロパティ
    http://msdn.microsoft.com/ja-jp/library/system.web.ui.webcontrols.objectdatasource.enablepaging(VS.80).aspx

     

    ページング用の SelectMethod と SelectCountMethod を拡張クラスに実装し
    ObjectDataSource の EnablePaging, SelectCountMethod 等のプロパティを
    適切に設定してやれば、あとは ListView の DataSourceID プロパティにそ
    の ObjectDataSource の ID を指定してやるだけで済みます。

     

    ListView と ObjectDataSource 間のページングのためのインターフェイスは
    何も考える必要はなく、そのためのコードを自力で作る必要もありません。

    ストアドではそう簡単にはいかないと思います。

     

    実は、先ほどまで ListView では試したことがなく、ListView との組み合わせ

    で問題ないか、いまいち自信がなかったというのが正直なところですが、検証

    したので確かです。(笑)

    2008年10月8日 12:38
  • おまけです。

     

    ご参考に、検証に使ったコードの一部をアップしておきますね。DB にはマイ
    クロソフトが無償で提供しているサンプル NORTHWND.MDF の Orders テーブル
    を使用しています。

     

    Code Snippet

    TableAdapter 拡張クラス

     

    using System;
    using System.Data;
    using System.Configuration;
    using System.Data.SqlClient;
    using System.ComponentModel;

    namespace OrdersDataSetTableAdapters
    {
        public partial class OrdersTableAdapter
        {
            [DataObjectMethod(DataObjectMethodType.Select, true)]
            public OrdersDataSet.OrdersDataTable GetDataByIndex(int startRowIndex, int maximumRows, int employeeid)
            {
                SqlDataAdapter adapter;
                if (employeeid == -1)
                {
                    string query = String.Format(
                        "SELECT * " +
                        "FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY [OrderID] ASC) AS rownum FROM [Orders]) " +
                        "AS DerivedTable " +
                        "WHERE rownum BETWEEN {0} AND {1} " +
                        "ORDER BY [OrderID] ASC",
                        startRowIndex + 1, maximumRows + startRowIndex);
                    adapter = new SqlDataAdapter(query, this.Connection);
                }
                else
                {
                    string query = String.Format(
                        "SELECT * " +
                        "FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY [OrderID] ASC) AS rownum FROM [Orders] " +
                        "WHERE [EmployeeID] = @EmployeeID) " +
                        "AS DerivedTable " +
                        "WHERE rownum BETWEEN {0} AND {1} " +
                        "ORDER BY [OrderID] ASC",
                        startRowIndex + 1, maximumRows + startRowIndex);
                    adapter = new SqlDataAdapter(query, this.Connection);
                    adapter.SelectCommand.Parameters.AddWithValue("@EmployeeID", employeeid);
                }
                OrdersDataSet dataset = new OrdersDataSet();
                adapter.Fill(dataset.Orders);
                return dataset.Orders;
            }


            public int GetNumberOfMessages(int employeeid)
            {
                SqlCommand sqlCmd;
                if (employeeid == -1)
                {
                    sqlCmd = new SqlCommand("SELECT COUNT(*) FROM [Orders]", this.Connection);
                }
                else
                {
                    sqlCmd = new SqlCommand("SELECT COUNT(*) FROM [Orders] WHERE [EmployeeID] = @EmployeeID", this.Connection);
                    sqlCmd.Parameters.AddWithValue("@EmployeeID", employeeid);
                }
                this.Connection.Open();
                int rows = (int)sqlCmd.ExecuteScalar();
                this.Connection.Close();
                return rows;
            }
        }
    }

     


    ObjectDataSource の設定

     

    <asp:ObjectDataSource ID="ObjectDataSource1"
        runat="server"
        EnablePaging="True"
        SelectCountMethod="GetNumberOfMessages"
        SelectMethod="GetDataByIndex"
        TypeName="OrdersDataSetTableAdapters.OrdersTableAdapter">
        <SelectParameters>
            <asp:ControlParameter ControlID="DropDownList1" DefaultValue="-1"
                Name="employeeid" PropertyName="SelectedValue" />
        </SelectParameters>
    </asp:ObjectDataSource>

     

     

    2008年10月8日 12:40
  •  SurferOnWww さんからの引用
     タク2007 さんからの引用

    ただ、App_Codeは動的生成したコードなどを入れておく特別なフォルダだと

    思うので、自ら作成したクラスは入れたくないなと、勝手に考えていますがどうなんでしょ。

    ビルドアクションにコンパイルを指定すれば大差はないので、解は無いのでしょうけど。

     

    「解」は App_Code フォルダに入れることだと思います。もともと、その目
    的で App_Code フォルダが用意されているそうですから。

     

    ASP.NET Web サイト内の共有コード フォルダ
    http://msdn.microsoft.com/ja-jp/library/t990ks23(VS.80).aspx

     

    "ページ間で共有するコードが Web アプリケーションに含まれている場合は、
    Web アプリケーションのルートの下にある 2 つの特殊フォルダ (Bin フォル
    ダおよび App_Code フォルダ) のいずれかでコードを保持できます。"

     

    アプリケーション内で利用する共通のクラスを作成する方法
    http://msdn.microsoft.com/ja-jp/library/cc719212.aspx

     

    "アプリケーション内の各ページで共通して利用するルーチンは、クラスとし
    て 1 箇所にまとめておくと便利です。ASP.NET 2.0 は、このような用途のた
    めに App_Code フォルダという特別なフォルダを用意しています。"


    多分ほとんどの人はそうしているのではないかと思います。特に、自分のよ
    うな VWD2005/2008 Express Edition(「Web アプリケーション」がテンプ
    レートに無いのです)ユーザーは、共有コードを App_Code フォルダ以外に
    置くということは、全くの考えの外なんです。(笑)

     

    VWD の場合、2008まではWebサイトプロジェクトしか作成できませんでしたから、共有コードというか、クラスのコードはApp_Codeフォルダに置かない限り動作しませんでした。

    だから、App_Codeを使っていた、ということはわかりますが、

     

    > 「解」は App_Code フォルダに入れることだと思います。もともと、その目
    > 的で App_Code フォルダが用意されているそうですから。

     

    このように言い切ることは問題だと思います。

     

    WebアプリケーションプロジェクトではソリューションエクスプローラからASP.NETフォルダの追加を選択した場合でも

    App_Codeフォルダはそもそも作成しないようになっています。
    基本的にはApp_CodeフォルダはWebサイトプロジェクト専用のもの、と考えておくのがよいかと。

     

    #Webアプリケーションプロジェクトではクラスのコードがどこにあってもコンパイルされます。

     したがって、App_Codeフォルダを自分で作成した場合でもコンパイルはされるので動作上の問題はでません。

     

    ちなみに、VWDでも2008のSP1からはWebアプリケーションプロジェクトが作成できるようになっています。
    SilverlightのプロジェクトやこれからリリースされるASP.NET MVCに対応できるようにするためのようです。

     

     

    2008年10月9日 0:44
  •  どっとねっとふぁん さんからの引用

    > 「解」は App_Code フォルダに入れることだと思います。もともと、その目
    > 的で App_Code フォルダが用意されているそうですから。

     

    このように言い切ることは問題だと思います。

     

    すいません、不適切な発言でした。Web アプリケーションプロジェクトの場
    合はおっしゃるとおりですね。

     

    App_Code フォルダに入れないとインテリセンスが働かないと思っていたの
    ですが、試してみたところ、Web サイトプロジェクトと違って、どこに置いても

    認識され、インテリセンスも働きました。

     

    .xsd ファイルは App_Code フォルダに入れないと、ObjectDataSource の「デ
    ータソースの構成」ウィザードの「ビジネスオブジェクトの選択」でビジネスオブ

    ジェクトを認識してくれないという不都合はありますが、クラスファイルはどこに

    置いてもよさそうですね。

     

    その他、自動生成される DataSet + TableAdapter のコードが App_Code フォ
    ルダ内に作成されること、他のプロジェクトの .aspx ファイルをエクスプローラで

    コピーして持ってきてもソリューションエクスプローラで認識されないこと等々、

    Web サイトプロジェクトとはまったく様子が違うのに驚きました。

     

    これだけ違うと、フォーラムで議論する前に、どちらのプロジェクトを使っている

    か確認しないと、話が噛み合わなくなりそうです。

    2008年10月9日 15:40
  • > .xsd ファイルは App_Code フォルダに入れないと、ObjectDataSource の「デ
    > ータソースの構成」ウィザードの「ビジネスオブジェクトの選択」でビジネスオブ

    > ジェクトを認識してくれないという不都合はありますが、

     

    ちょっときになったのでためしてみました。

    xsdファイルを作成したあと、一度ビルドしておいて、ビジネスオブジェクトの選択で

    データコンポーネントのみを表示のチェックをはずせばデータセットがどこにあっても

    認識してくれると思います。

     

    Webアプリケーションの場合はインテリセンスを働かせるのに一度ビルドが必要

    なはずなので、そのあたりに注意してればよいかと。

     

    > これだけ違うと、フォーラムで議論する前に、どちらのプロジェクトを使っている

    > か確認しないと、話が噛み合わなくなりそうです。

     

    そうですね。

    プロジェクトによって動きが違うようなところの質問があがってきたときは、まず

    どっちか確認するようにしてます。

    ただ、その質問の意味がわからない(自分がWebサイトを使っているかWeb

    アプリケーションを使っているか認識していない)場合が多いんですよね。。。

    2008年10月10日 1:11
  • SurferOnWwwさん どっとねっとふぁんさん

    色々ご助言、有難う御座いました。

    私も備忘録を兼ねて、1つWebアプリケーションのApp_Codeフォルダで気がついた事を1つ。
    App_Codeフォルダの中にクラスファイルを新規で作ると、ビルドアクションがコンテンツ
    になり、その他のフォルダでクラスファイルを作ると、コンパイルになります。

    で、これがどんな影響を及ぼすかというと、上記でも指摘があるインテリセンスが働かない。。。
    OjbectDataSourceのウィザードで出てこないといった事になります。。。

    ビルドアクションなんて、余り気にしないところなのでWebサイトプロジェクトから移ってきた人とか
    結構はまる気がしました。

     

    なぜにWebアプリケーションでApp_Codeフォルダが出てきたのか(作ったのか)というと

    このフォルダの中にDataSetを作らないとObjectDataSourceのウィザードに出てこない

    と思ってしまったからです

    (こちらは、上記でご指摘頂いている通りなので、ちょっといじるとちゃんと出てきますね)。



    このたびはトピックとはずれてしまった話題も含めて、有難う御座いました。

    2008年10月10日 5:44