ASP.NET Webアプリケーションに、基本的にアドホックレポートを生成するためのツールであるページがあります。ユーザーは多数の基準に値を設定し、それらを送信して結果セットを取得します。結果を取得するために必要なSQLは、実行時に生成されます。コードでは、SQLを使用してSqlDataSourceを作成し、それをListViewに関連付けます。その時点まで、すべてが正常に機能しています。
私が理解できないのは、次に、ListViewの列を動的に生成する方法です。問題は、動的に生成されたSQLの出力に依存しているため、コンパイル時に列の数/名前がわからないという事実にあります。これは非常に単純な小さな演習になると思いましたが、これを行う方法を示す簡単な例を見つけることができないようです。
私は基本的にゼロからの例を求めているので、私の既存のコードはほとんど無関係です。私のアプローチが正しいかどうかさえわかりません。つまり、マークアップでListViewを使用し、実行時にコードでそのテンプレートを操作しようとしています。ただし、ここにいくつかのスニペットがあります...
参照のために、SQLを生成する私のメソッドは次のとおりです。
public static string GetReportSQL(HttpContext c = null)
{
if (c.Equals(null)) c = HttpContext.Current;
string report_id = c.Request.Params["report_id"].ToString();
string select_list = null;
string where_list = null;
string field = null;
string criteria_value = null;
POST.App_Objects.Report report = new POST.App_Objects.Report();
POST.App_Objects.Report report_fields = new POST.App_Objects.Report();
DataSet rds = report.GetReport_Summary_ByID(Int32.Parse(report_id));
DataSet rfds = report_fields.GetReportFields(Int32.Parse(report_id));
foreach (DataRow f in rfds.Tables[0].Rows)
{
field = f["report_field_name"].ToString();
if (!String.IsNullOrEmpty(c.Request["show_field__" + field]))
{
select_list += (!String.IsNullOrEmpty(select_list) ? ", " : null) + field + " AS '" + f["report_field_title"].ToString() + "'";
}
if (!String.IsNullOrEmpty(c.Request["criteria_value__" + field]))
{
criteria_value = c.Request["criteria_value__" + field].ToString();
where_list += (!String.IsNullOrEmpty(where_list) ? " AND " : null) + field;
switch (f["report_field_filter_type"].ToString())
{
case FILTER_TYPE_SEARCH_TERM:
where_list += " LIKE '%" + criteria_value + "%'";
break;
case FILTER_TYPE_TEXT_LIST:
break;
case FILTER_TYPE_MULTIPLE_SELECT:
where_list += " IN ('" + criteria_value.Replace(",", "','") + "')";
break;
}
}
}
string sql = "SELECT " + select_list + " FROM " + rds.Tables[0].Rows[0]["report_definition_source"].ToString() + " WHERE " + where_list;
return sql;
}
これがListViewコントロールのInitメソッドで、上記のSQL生成コードに基づいてSqlDataSourceに関連付けられています。
public void ReportResultListView_Init(object sender, ListViewEditEventArgs e)
{
ListView rlv = (ListView)ReportFormView.FindControl("ReportResultListView");
SqlDataSource rds = new SqlDataSource(
ConfigurationManager.ConnectionStrings["POST"].ConnectionString.ToString(),
GetReportSQL(HttpContext.Current)
);
rlv.DataSource = rds;
ListViewDataItem lvdi = new ListViewDataItem(0,0);
rlv.Items.Add(lvdi);
rlv.DataBind();
}
そして最後に、関連するListView(FormView内にあります。参考までに)を取得したマークアップのスニペットを次に示します。
<asp:ListView
ID="ReportResultListView"
OnInit="ReportResultListView_Init"
runat="server">
<ItemTemplate>
<li><%# Eval("Organization Code").ToString() %></li>
</ItemTemplate>
<EmptyDataTemplate>
Nothing.
</EmptyDataTemplate>
</asp:ListView>
テスト用に1つのバインダー(「組織コード」)があります。特定の列が表示されることはわかっています。明確にするために、私が求めているのは、実行時に出力するフィールドを指定することです。それらの名前は、別のクエリの結果です...
もちろん、これが可能であることは知っていますが、必要なものに合った例が見当たらないだけです。私が.NETにそれほど慣れていなかったとしたら、これはかなり明白だと思います...