Visual C# .NETのRepeaterの入れ子について
以前、Repeaterについて書きましたが、
今回は、RepeaterのRepeater、、、Repeaterの入れ子について書きたいと思います。
2つのテーブルをJOINして取得するには、構造が複雑だったり、データ量が多い事によりJOINが不可能な場合があります。
そこで、2つのテーブルを別々で取得した場合の、Repeater用のデータ取得方法と、画面側の実装方法をご説明します。
サンプルデータ
以下のように2つのテーブルがあったとします。
とてもシンプルなデータなので、JOINして取ればいいですが、
このデータをRepeaterの入れ子用にデータを取得したいと思います。
■ユーザー情報(DB名:User) UserID Name ----------------------------------- 1 Kobayashi 2 Tanaka 3 Yamada ■好きなフルーツ(DB名:Favorite) UserID Fruits ----------------------------------- 1 パイナップル 1 バナナ 1 りんご 2 いちご 2 キュウイ 3 レモン
Repeaterの入れ子用にデータを取得
(1)ユーザー情報を取得して、画面側の実装のRepeaterタグ、id=userListにDataBind()します。
(2)DB:Userと、DB:Favoriteの構造を作成し、どのカラムでリレーションさせるかを設定します。
ここでは以下のように設定します。
リレーションさせるカラム ⇒ 『UserID』
リレーション名 ⇒ 『UserFavorite』
(3)ユーザー情報を取得し、DataSetへセットします。
(4)(3)で取得したユーザーIDを元に、Favorite情報を取得し、DataSetへセットします。
※データベースは、Microsoft SQL Serverへの接続で説明しています。
※エラーが発生した場合は、ログ出力するようにしています。
// ---(1)DataSet作成------------------------------------- protected void Page_Load(object sender, EventArgs e) { // ユーザー情報と、好きなフルーツを取得 userList.DataSource = GetUser(tableDataGeteway); userList.DataBind(); } // ---(1)---END------------------------------------------ /// <summary> /// ユーザー情報と、好きなフルーツを取得 /// </summary> /// <returns>ユーザー情報、好きな食べ物を1つにまとめたDataSet</returns> public DataSet GetUser() { // DataSetの初期化 DataSet dataSet = new DataSet(); //コネクション取得 SqlConnection cnn = new SqlConnection("server=(local);database=pubs; Integrated Security=SSPI"); try { cnn.Open(); // ---(2)DataSet作成-------------------------------------- // DataTable(User)の作成 DataTable table = new DataTable("User"); dataSet.Tables.Add(table); table.Columns.Add("UserID", typeof(string)); table.Columns.Add("Name", typeof(string)); table.PrimaryKey = new DataColumn[] { table.Columns["UserID"] }; // DataTable(Favorite)の作成 table = new DataTable("Favorite"); dataSet.Tables.Add(table); table.Columns.Add("UserID", typeof(string)); table.Columns.Add("Fruits", typeof(string)); // リレーション dataSet.Relations.Add("UserFavorite", dataSet.Tables["User"].Columns["UserID"], dataSet.Tables["Favorite"].Columns["UserID"]); // ---(2)---END------------------------------------------ // ---(3)ユーザー情報取得してDataSetに入れ直し----------- SqlDataAdapter sqlUser = new SqlDataAdapter("SELECT UserID, Name from User ", cnn); DataTable dtUser = new DataTable(); int recordsUser = sqlUser.Fill(dtUser); if (recordsUser > 0) { for (int i = 0; i < dtUser.Rows.Count; i++) { // 1レコード取得 DataRow rowUser = dtUser.Rows[i]; // 取得したユーザー情報をセット dataSet.Tables["User"].Rows.Add( new object[] { rowUser["UserID"].ToString(), rowUser["Name"].ToString(), }); // ---(3)---END------------------------------------------ // ---(4)ユーザーIDから好きな食べ物情報取得してDataSetに入れ直し--- // 好きな食べ物を取得 SqlDataAdapter sqlFav = new SqlDataAdapter( "SELECT UserID, Fruits from Favorite where UserID = " + rowUser["UserID"].ToString(), cnn); DataTable dtFav = new DataTable(); int recordsFav = sqlFav.Fill(dtFav); if (recordsFav > 0) { // 取得した好きな食べ物情報をセット foreach (DataRow rowFav in dtFav.Rows) { dataSet.Tables["Favorite"].Rows.Add( new object[] { rowFav["UserID"].ToString(), rowFav["Fruits"].ToString(), }); } } // ---(4)---END-------------------------------------------------------- } } } catch (SqlException e) { string msg = ""; for (int i = 0; i < e.Errors.Count; i++) { msg += "Error #" + i + " Message: " + e.Errors[i].Message + "\n"; } System.Console.WriteLine(msg); } finally { if (cnn.State != ConnectionState.Closed) { cnn.Close(); } } return dataSet; }
画面側の実装
入れ子にしている部分のRepeaterの記述は、上記で設定したリレーション名を設定します。『UserFavorite』
また、カラムを取得する場合、入れ子の部分のみ、"[\"Fruits\"]" の様な記述になることに注意してください。
<table class="p" border="1" cellspacing="0" cellpadding="3" width="100%"> <!-- 項目表示 --> <tr align="center"> <th>ユーザーID</th> <th>名前</th> <th>好きな食べ物</th> </tr> <!-- 繰り返し処理部分 start --> <asp:Repeater id="userList" runat="server"> <ItemTemplate> <tr align="center"> <td> <!-- ユーザID --> <%# DataBinder.Eval(Container.DataItem, "UserID") %> </td> <td> <!-- ユーザ名 --> <%# DataBinder.Eval(Container.DataItem, "Name") %> </td> <td> <asp:Repeater id="userFavoriteList" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("UserFavorite") %>' runat="server"> <ItemTemplate> <li> <div class="user"> <!-- 好きなフルーツ --> <%# DataBinder.Eval(Container.DataItem, "[\"Fruits\"]") %> </div> </li> </ItemTemplate> </asp:Repeater> </td> </tr> </ItemTemplate> </asp:Repeater> <!-- 繰り返し処理部分 end --> </table>