.NET TIPS

[ASP.NET]Repeaterコントロールでネストされたデータを表現するには?

山田 祥寛
2005/05/20

 データベースから一覧表を生成する場合に、階層構造を持った情報を表示したいというケースは多くある。例えば、以下のような一覧表が好例だろう。

Repeaterコントロールによる階層構造を持ったデータセットの表示
シリーズの一覧と、各シリーズに属する記事の一覧を階層構造で表示している。

 本稿では、このような階層構造を持った情報をRepeaterコントロールで表示する方法について紹介しよう。なお、本稿のサンプルを動作させるには、あらかじめデータベース上に以下の2つのテーブル(seriesテーブルとarticleテーブル)を作成し、適当なデータを入力しておく必要がある。

フィールド名 データ型 概要
sid VARCHAR(10) シリーズID(主キー)
stitle VARCHAR(100) シリーズ・タイトル
seriesテーブルのフィールド・レイアウト
 
フィールド名 データ型 概要
aid INT 記事ID(主キー、連番)
atitle VARCHAR(100) 記事タイトル
sid VARCHAR(10) シリーズID(seriesテーブルのsidフィールドの外部キー)
url VARCHAR(255) 記事URL
articleテーブルのフィールド・レイアウト

 表の内容からも分かるように、これらの2つのテーブルでは、外部キーによりリレーション(リレーションシップ)が設定されている。

 それではさっそく、具体的なサンプル・コードを眺めてみることにしよう。

<%@ Page Language="C#" ContentType="text/html" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="Server">
void Page_Load(Object sender, EventArgs e) {
  SqlConnection db = new SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet");

  // series、articleの各テーブルからDataSetにデータを取得
  SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM series", db);
  DataSet ds = new DataSet();
  db.Open();
  da.Fill(ds, "series");
  da.SelectCommand = new SqlCommand("SELECT * FROM article",db);
  da.Fill(ds, "article");
  db.Close();

  // DataSet内のseriesテーブル、articleテーブルに対して
 
// リレーションを設定
  ds.Relations.Add("SeriesRelate",
    ds.Tables["series"].Columns["sid"], ds.Tables["article"].Columns["sid"]);
  rep.DataSource = ds.Tables["series"];
  rep.DataBind();
}
// 子テーブルのDataViewオブジェクトを取得
DataView GetChild(Object item, String relName) {
  return ((DataRowView)item).CreateChildView(relName); 
}
</script>
<asp:Repeater id="rep" runat="Server">
  <HeaderTemplate>
    <dl>
  </HeaderTemplate>
  <ItemTemplate>
    <dt>
      <%# DataBinder.Eval(Container.DataItem,"sTitle") %>
    </dt>
    <dd>
      <asp:Repeater id="repArt" runat="Server"
        DataSource='<%# GetChild(Container.DataItem,"SeriesRelate") %>'> 
        <HeaderTemplate>
          <ol>
        </HeaderTemplate>
        <ItemTemplate>
          <li>
            <asp:HyperLink id="link" runat="Server"
              NavigateUrl='<%# DataBinder.Eval(Container.DataItem,"url") %>'
              Text='<%# DataBinder.Eval(Container.DataItem,"aTitle") %>' />
          </li>
        </ItemTemplate>
        <FooterTemplate>
          </ol>
        </FooterTemplate>
      </asp:Repeater>
    </dd>
  </ItemTemplate>
  <FooterTemplate>
    </dl>
  </FooterTemplate>
</asp:Repeater>
ネストされたデータセットをRepeaterコントロールで表示するサンプル・プログラム(C#版:nest_cs.aspx)
の内容は後述する。
 
<%@ Page Language="VB" ContentType="text/html" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="Server">
Sub Page_Load(sender As Object, e As EventArgs)
  Dim db As New SqlConnection("Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=dotnet")

  ' series、articleの各テーブルからDataSetにデータを取得
  Dim da As New SqlDataAdapter("SELECT * FROM series", db)
  Dim ds As New DataSet()
  db.Open()
  da.Fill(ds, "series")
  da.SelectCommand = New SqlCommand("SELECT * FROM article", db)
  da.Fill(ds, "article")
  db.Close()

  ' DataSet内のseriesテーブル、articleテーブルに対して
  ' リレーションを設定
  ds.Relations.Add("SeriesRelate", _
    ds.Tables("series").Columns("sid"),ds.Tables("article").Columns("sid"))
  rep.DataSource = ds.Tables("series")
  rep.DataBind()
End Sub
' 子テーブルのDataViewオブジェクトを取得
Function GetChild(item As Object, relName As String) As DataView
  Return CType(item, DataRowView).CreateChildView(relName) 
End Function
</script>
<asp:Repeater id="rep" runat="Server">
  <HeaderTemplate>
    <dl>
  </HeaderTemplate>
  <ItemTemplate>
    <dt>
      <%# DataBinder.Eval(Container.DataItem,"sTitle") %>
    </dt>
    <dd>
      <asp:Repeater id="repArt" runat="Server"
        DataSource='<%# GetChild(Container.DataItem,"SeriesRelate") %>'> 
        <HeaderTemplate>
          <ol>
        </HeaderTemplate>
        <ItemTemplate>
          <li>
            <asp:HyperLink id="link" runat="Server"
              NavigateUrl='<%# DataBinder.Eval(Container.DataItem,"url") %>'
              Text='<%# DataBinder.Eval(Container.DataItem,"aTitle") %>' />
          </li>
        </ItemTemplate>
        <FooterTemplate>
          </ol>
        </FooterTemplate>
      </asp:Repeater>
    </dd>
  </ItemTemplate>
  <FooterTemplate>
    </dl>
  </FooterTemplate>
</asp:Repeater>
ネストされたデータセットをRepeaterコントロールで表示するサンプル・プログラム(VB.NET版:nest_vb.aspx)
の内容は後述する。

 本稿のデータセット(DataSetオブジェクトである変数ds)にはseries、articleという名前の2つのテーブルが含まれる。ここでポイントとなるのは、2つのテーブルに対して、リレーションを設定しなければならないという点だ。データセット内のリレーションは、DataRelationCollectionオブジェクト(System.Data名前空間)のAddメソッドで追加可能だ(DataRelationCollectionオブジェクトは、データセットのRelationsプロパティから取得できる)。

 本稿の例では、seriesテーブルのsidフィールドとarticleテーブルのsidフィールドとの間にリレーションを設定している。

seriesテーブルとarticleテーブルの間に設定されたリレーション

 リレーションを設定してしまえば、あとは簡単だ。

 データセット内のテーブル間にリレーションが設定されている場合、親テーブルの行から関連する子テーブルのデータビュー(DataViewオブジェクト)を取得できる。データビューの取得には、親テーブルの行(すなわち、Repeaterコントロール内ではContainer.DataItemプロパティで取得可能なデータ行)に対して、DataRowViewオブジェクトのCreateChildViewメソッドを実行すればよい()。CreateChildViewメソッドには、先ほどAddメソッドで宣言したリレーション名(ここでは“SeriesRelate”)、またはDataRelationオブジェクト(System.Data名前空間)を指定できる。

 あとは、取得したデータビューをネストされたRepeaterコントロールのDataSource属性に設定すればよいだけだ()。これで、入れ子となった内部のRepeaterコントロールで子テーブル(のデータビュー)の列を参照することができるようになる。

 以上が理解できたら、サンプル・コードを実行してみよう。本稿冒頭のような結果を得られれば成功だ。End of Article

カテゴリ:Webフォーム 処理対象:Repeaterコントロール
使用ライブラリ:Repeaterコントロール
使用ライブラリ:DataSetクラス(System.Data名前空間)
使用ライブラリ:DataRelationCollectionクラス(System.Data名前空間)
使用ライブラリ:DataRelationクラス(System.Data名前空間)
使用ライブラリ:DataViewクラス(System.Data名前空間)
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]DataGridコントロールを階層表示させるには?
[ADO.NET]複数のselect文をまとめて実行するには?
[LINQ to SQL]関連するテーブル内容を先に読み込んでおくには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間