SPGridView(GridViewに基づくSharePointコントロール)でObjectDataSourceを使用しており、ログを見ると、SelectMethodが9回呼び出されています。これは、実際に必要な回数の8倍です。
ObjectDataSourceオブジェクトがSelectメソッドを呼び出す条件、またはチェックする項目の大きなリスト/これを最適化するための提案を誰かが正確に知っているかどうか疑問に思いましたか?それはDataBoundなので、それはすべてSPGridViewにかかっているということですか?
selectcountmethodが(このSOの回答に従って)一度呼び出すことは知っていますが、なぜselectメソッドを何度も呼び出す必要があるのかよくわかりません。私は間違ったステップで拘束していますか?間違ったステップで初期化していますか?また、ページング、並べ替え、フィルタリングを有効にしています...どんなヒントでも素晴らしいでしょう:)
編集:イベントにログコードを追加しましたが、GridViewのDataBindingイベントが複数回ヒットしているようです。つまり、内部的にSPGridViewがDataBind()を複数回呼び出しているということですか?私が呼び出す唯一のDataBind()は、ユーザーコントロールのRenderイベントであり、これは1回だけ発生します。
ロギングトレース:
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
...
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
....
GridView_RowDataBound
ODS_Selecting
ODS_ObjCreating
ODS_Selecting
Gridview_DataBinding
GridView_RowDataBound
....
GridView_RowDataBound
また、ここにコードの大きな塊があります!
.ascx:
<SharePoint:SPGridView ID="appGridView" DataSourceID="appODS" AutoGenerateColumns="false"
AllowPaging="true" PageSize="10" AllowSorting="true"
AllowFiltering="true" FilterDataFields=",,,,TimeElapsed,,," FilteredDataSourcePropertyName="FilterExpression" FilteredDataSourcePropertyFormat="{1} = '{0}'"
runat="server" />
<wc:ObjectDataSource ID="appODS" runat="server" />
<SharePoint:SPGridViewPager ID="appGridViewPager" runat="server" GridViewId="appGridView" />
.ascx.cs:
パブリック部分クラスMyUserControl:UserControl {
//http://www.reversealchemy.net/blog/2009/05/01/building-a-spgridview-control-part-1-introducing-the-spgridview/
//http://www.reversealchemy.net/2009/05/24/building-a-spgridview-control-part-2-filtering/
protected override void OnInit(EventArgs e)
{
appODS.EnablePaging = true;
appODS.SelectMethod = "GetMyDataTable";
appODS.SelectCountMethod = "GetMyDataTableCount";
appODS.StartRowIndexParameterName = "rowStart";
appODS.MaximumRowsParameterName = "rowCount";
appODS.SelectParameters.Add(new Parameter { Name = "myParam", DefaultValue = "test" });
appODS.TypeName = this.GetType().AssemblyQualifiedName;
appODS.ObjectCreating += new ObjectDataSourceObjectEventHandler(appODS_ObjectCreating);
appGridView.RowDataBound += new GridViewRowEventHandler(appGridView_RowDataBound);
appODS.Filtering += new ObjectDataSourceFilteringEventHandler(appODS_Filtering);
appGridView.Sorting += new GridViewSortEventHandler(appGridView_Sorting);
}
//https://stackoverflow.com/questions/1351578/spgridview-data-and-correct-method-of-ensuring-data-is-safe
protected override void OnPreRender(EventArgs e)
{
if (!string.IsNullOrEmpty(appODS.FilterExpression))
{
appODS.FilterExpression = string.Format(
appGridView.FilteredDataSourcePropertyFormat,
appGridView.FilterFieldValue.Replace("'", "''"),
appGridView.FilterFieldName
);
}
base.OnPreRender(e);
}
private void appODS_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = this;
}
protected sealed override void Render(HtmlTextWriter writer)
{
GenerateColumns();
appGridView.DataBind();
base.Render(writer);
}
public DataTable GetMyDataTable(string myParam, int rowStart, int rowCount)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(Int32));
// more columns here
dt.Columns.Add("TestColumn", typeof(decimal));
List<Stuff> things = svc.GetStuff();
foreach (Stuff thing in things)
{
dt.Rows.Add(
thing.Blah, thing.Blah2);
}
return dt;
}
public int GetMyDataTableCount(string myParam)
{
return 10003; //faked out for now
}
private void GenerateColumns()
{
BoundField column = new BoundField();
column.DataField = "ID";
column.SortExpression = "ID";
column.HeaderText = "ID";
appGridView.Columns.Add(column);
//more
column = new BoundField();
column.DataField = "TestColumn";
column.SortExpression = "TestColumn";
column.HeaderText = "TestColumn";
appGridView.Columns.Add(column);
}
////filtering
protected sealed override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (Context.Request.Form["__EVENTARGUMENT"] != null &&
Context.Request.Form["__EVENTARGUMENT"].EndsWith("__ClearFilter__"))
{
// Clear FilterExpression
ViewState.Remove("FilterExpression");
}
}
private void appODS_Filtering(object sender, ObjectDataSourceFilteringEventArgs e)
{
ViewState["FilterExpression"] = ((ObjectDataSourceView)sender).FilterExpression;
}
private void appGridView_Sorting(object sender, GridViewSortEventArgs e)
{
if (ViewState["FilterExpression"] != null)
{
appODS.FilterExpression = (string)ViewState["FilterExpression"];
}
}
private void appGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (sender == null || e.Row.RowType != DataControlRowType.Header)
{
return;
}
SPGridView grid = sender as SPGridView;
if (String.IsNullOrEmpty(grid.FilterFieldName))
{
return;
}
// Show icon on filtered column
for (int i = 0; i < grid.Columns.Count; i++)
{
DataControlField field = grid.Columns[i];
if (field.SortExpression == grid.FilterFieldName)
{
Image filterIcon = new Image();
filterIcon.ImageUrl = "/_layouts/images/filter.gif";
filterIcon.Style[HtmlTextWriterStyle.MarginLeft] = "2px";
// If we simply add the image to the header cell it will
// be placed in front of the title, which is not how it
// looks in standard SharePoint. We fix this by the code
// below.
Literal headerText = new Literal();
headerText.Text = field.HeaderText;
PlaceHolder panel = new PlaceHolder();
panel.Controls.Add(headerText);
panel.Controls.Add(filterIcon);
e.Row.Cells[i].Controls[0].Controls.Add(panel);
break;
}
}
}
}