WebForms 개발시 Repeater를 자주 사용하게 된다. (회사마다 다르겠지만)
Repeater 사용시 중첩으로 사용하고 싶은 경우들이 있다.
예를들어.
A사 (Key: A) | |
A-1 계열사 (FKey: A) | |
B사 (Key: B) | |
B-1 계열사 (FKey: B) | |
B-2 계열사 (FKey: B) |
위와 같은 테이블을 만들기 위해 중첩 Repeater를 사용할 수 있다. (물론 DB조회를 잘 해와서 하나의 Repeater로도 충분히 표현 가능하다. 예시일뿐.)
사용하려는 방법은 DataSet의 Relations를 활용한 방법이다.
* MS Docs DataRelation 참고
Relations를 활용하면 키값으로 두개의 DataTable을 묶어서 사용할 수 있다.
구글링을 하여 찾아보면, OnItemDataBound에서 한번 더 쿼리를 실행해 바인딩(부모의 매 Row마다 실행)하는 방법을 많이 볼 수 있다.
하지만 DataRelation을 사용하면 한번의 쿼리 실행으로 원하는 결과를 만들 수 있다.
코드를 확인하며 이해해보자
[aspx]
Repeater 두개를 중첩하여 작성하였다.
OnItemDataBound에서 Relation정보를 찾아와 SubCompanyList에 바인딩 한다.
* MS Docs DataBinder.Eval 참고
<table> <tbody> <asp:Repeater ID="CompanyList" runat="server" OnItemDataBound="CompanyList_ItemDataBound"> <ItemTemplate> <tr> <td><%# Eval("Name") %> (Key: <%# Eval("Key") %>)</td> <td> </td> </tr> <asp:Repeater ID="SubCompanyList" runat="server"> <ItemTemplate> <tr> <td> </td> <td><%# DataBinder.Eval(Container.DataItem, "[\"Name\"]") %> (FKey: <%# DataBinder.Eval(Container.DataItem, "[\"FKey\"]") %>)</td> </tr> </ItemTemplate> </asp:Repeater> </ItemTemplate> </asp:Repeater> </tbody> </table> |
[aspx.cs]
1. Page_Load에서 dtCompany, dtSubCompany(임시로 만든 정보입니다. 현업에서는 DB를 읽어와 사용하겠죠?)를 불러와 DataSet을 생성한다.
2. DataSet.Relations를 추가 하여 관계를 생성한다. (관계의 이름은 "CompanyKey"이다.)
* Relations의 파라미터로 "관계의 이름", "부모 키 컬럼", "자식 키 컬럼"을 넣어준다.
3. 최상단 Repeater에 부모 Table을 바인딩한다.
4. OnItemDataBound Event에서 자식 Table을 찾아 Sub Repeater에 바인딩한다. (GetChildRows 함수 사용)
protected void Page_Load(object sender, EventArgs e) { var dtCompany = InitCompanyData(); var dtSubCompany = InitSubCompanyData(); // 데이터셋 생성 var ds = new DataSet(); ds.Tables.Add(dtCompany); ds.Tables.Add(dtSubCompany); // 관계 설정 // DB 조회시에는 SP에서 테이블을 여러개 읽어와 Fill로 DataSet을 만든 후 Relation만 잡아주면 된다. ds.Relations.Add("CompanyKey", ds.Tables["CompanyTable"].Columns["Key"], ds.Tables["SubCompanyTable"].Columns["FKey"]); // 부모 테이블 바인딩 CompanyList.DataSource = ds.Tables["CompanyTable"]; CompanyList.DataBind(); }
private DataTable InitCompanyData() { var dtCompany = new DataTable(); dtCompany.TableName = "CompanyTable"; dtCompany.Columns.Add("Key", typeof(string)); dtCompany.Columns.Add("Name", typeof(string)); var newRow = dtCompany.NewRow(); newRow["Key"] = "A"; newRow["Name"] = "A사"; dtCompany.Rows.Add(newRow); newRow = dtCompany.NewRow(); newRow["Key"] = "B"; newRow["Name"] = "B사"; dtCompany.Rows.Add(newRow); return dtCompany; }
private DataTable InitSubCompanyData() { var dtSubCompany = new DataTable(); dtSubCompany.TableName = "SubCompanyTable"; dtSubCompany.Columns.Add("FKey", typeof(string)); dtSubCompany.Columns.Add("Name", typeof(string)); var newRow = dtSubCompany.NewRow(); newRow["FKey"] = "A"; newRow["Name"] = "A-1 계열사"; dtSubCompany.Rows.Add(newRow); newRow = dtSubCompany.NewRow(); newRow["FKey"] = "B"; newRow["Name"] = "B-1 계열사"; dtSubCompany.Rows.Add(newRow); newRow = dtSubCompany.NewRow(); newRow["FKey"] = "B"; newRow["Name"] = "B-2 계열사"; dtSubCompany.Rows.Add(newRow); return dtSubCompany; }
protected void CompanyList_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { Repeater SubCompanyList = e.Item.FindControl("SubCompanyList") as Repeater; // 관계가 설정된 자식 테이블 얻어오기 // 이 부분에서 한번 더 쿼리를 실행할 필요 없이, 관계가 맺어진 정보를 읽어올 수 있다. var childRows = ((DataRowView)e.Item.DataItem).Row.GetChildRows("CompanyKey"); SubCompanyList.DataSource = childRows; SubCompanyList.DataBind(); } } |
[결과]
직접 디버깅을 해보면 알겠지만 OnItemDataBound Event에서 부모 Table의 Row에 자식 테이블이 엮여 있는것을 볼 수 있다.
* DB조회시 까다로운 쿼리 혹은 전혀 관계 없는 데이터를 코드딴에서 묶어서 사용하고 싶을때도 유용하게 사용가능하다. 일자별로 묶어서 데이터를 처리한다던가 하는 그런것들 말이다.
다음번 글은 MS사의 Bot Framework와 Language Understanding(LUIS:루이스)을 작성해볼까 한다. (텔레그램, 스카이프 등등 연동도 간편하고 좋다. 단지 LUIS가 유료)
끗.
'SW > ASP.NET' 카테고리의 다른 글
[ASP.NET] Nested Repeater(중첩리피터)를 사용 - 3중 리피터 (0) | 2019.12.16 |
---|---|
[ASP.NET] 비하인드 코드(cs)에서 버튼 클릭 이벤트 실행시키기 (0) | 2019.12.16 |
[ASP.NET] TextBox 입력시 다른 컨트롤 이벤트 발생시키기 (0) | 2019.12.16 |
[ASP.NET] 파일 업로드 / 다운로드 (0) | 2019.09.19 |
[ASP.NET] Login & Logout - 폼 인증 (0) | 2019.09.19 |