2010-11-29 7 views
2

참고 :이 예제는 더 간단한 예제가 있으므로 완전히 수정되었습니다.ListView + ObjectDataSource SelectMethod는 EnableViewState = "false"인 경우 두 번 호출됩니다.

ListViewObjectDataSource 만있는 샘플 페이지를 설정했습니다. 처음으로 페이지가 나타나면 (!IsPostBack) 내 GetList 메서드가 한 번 호출됩니다. 페이징 (IsPostBack) 후에는 GetList 메서드가 두 번 호출됩니다. 이전의 페이징 값에서는 처음으로, 새 값에서는 두 번째로 호출됩니다.

ListViewEnableViewState="true"을 설정하면 GetList 메서드는 한 번만 호출됩니다. ListViewViewState에서 가져 오거나 메소드를 다시 실행하여 "초기 상태"를 원합니다.

ListView에서 ViewState를 사용 중지하고 SelectMethod이 두 번 호출되지 않도록 할 수 있습니까?

ASPX 페이지 : 코드 숨김

<asp:ListView ID="TestListView" runat="server" DataSourceID="ODS" EnableViewState="false"> 
     <LayoutTemplate> 
      <asp:PlaceHolder ID="itemPlaceHolder" runat="server" /> 

      <asp:DataPager ID="TestPager" runat="server" PageSize="10"> 
       <Fields> 
        <asp:NumericPagerField /> 
       </Fields> 
      </asp:DataPager> 
     </LayoutTemplate> 
     <ItemTemplate> 
      <div><%# Eval("Title") %></div> 
     </ItemTemplate> 
    </asp:ListView> 

    <asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="GetList" SelectCountMethod="GetListCount" 
     TypeName="Website.Test" EnablePaging="true" /> 

ASPX이 :

namespace Website 
{ 
    public partial class Test : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     public IList<DataItem> GetList(int maximumRows, int startRowIndex) 
     { 
      return GetListEnumerable().Skip(startRowIndex).Take(maximumRows).ToList(); 
     } 

     public IEnumerable<DataItem> GetListEnumerable() 
     { 
      for (int i = 0; i < 100; i++) 
      { 
       yield return new DataItem { Title = i.ToString() }; 
      } 
     } 

     public int GetListCount() 
     { 
      return 100; 
     } 
    } 

    public class DataItem 
    { 
     public string Title { get; set; } 
    } 
} 

답변

2

하나에 ODS 캐싱을 켜십시오.

<asp:ObjectDataSource ID="ODS" ... EnableCaching="true" /> 

이렇게하면 새 데이터가 필요할 때만 GetList가 호출됩니다. 이미 검색된 데이터가있는 페이지로 포스트 백하면 캐시 된 버전을 사용하고 GetList를 호출하지 않습니다.

또는 ListView에서 DataPager를 이동하고 PagedControlID 속성을 설정하십시오.

+0

내가 캐싱 생각을하지만, 내 경우 (10 초 길어야 말)가 무한 매개 변수 가능성, 그래서 캐시의 지속 시간이 매우 작은 수 할 것입니다. 사용자가 10 초 후에 페이지를 열면 여전히 쿼리가 두 배가되어 페이지가 상당히 느려집니다. ViewState를 사용하면 더 나은 옵션이됩니다. ListView에서 DataPager를 옮기지 못해도 여전히 두 번 쿼리되었습니다. 나는 직접적으로 또는 간접적으로 (Reflection을 통해)'BaseDataBoundControl.RequiresDataBinding'을 설정할 수 있는지 궁금합니다. –

+0

Reflection을 통해'RequiresDataBinding'을 false로 설정하려고 시도하여 이중 쿼리를 방지합니다. 그러나 그것은 발생하는 첫 번째 쿼리 (페이징 전) 일 뿐이므로 사용할 수 없습니다. 이제 ViewState를 떠날 것입니다. –

+0

매개 변수에 대해 생각하지 않았습니다. 캐시가 어떻게 구현되는지는 잘 모르겠습니다. 그러나,리스트 뷰에서 페이저를 움직이면 나에게 트릭이 생겼다. 나는 그것이 믿을만한 해결책이 아니라고 생각한다. RequiresDataBinding은 여러 위치에서 재정의됩니다. 시간이 허락한다면 ListView에서 자신의 컨트롤을 만들고 CreateChildren과 RequiresDataBinding을 처리 할 수 ​​있습니다. 그렇다면 항상 ViewState가 있습니다. :) – Ruslan

0

실제로 OnSelecting 이벤트를 사용해야합니다. 어떻게됩니까

은 ObjectDataSource를이 방법은 두 번 데이터를 가져

  1. 처음 을 경우 SelectMethod 호출하는 것입니다.
  2. 다음 번에는 계산됩니다.

그래서 난 당신이 OnSelecting 이벤트를

<asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="GetList" SelectCountMethod="GetListCount" 
    OnSelecting="ods_Selecting"> 
    TypeName="Website.Test" EnablePaging="true" /> 

을 구현하고 ObjectDataSource를이 카운트 메소드를 호출 할 때 다음 이벤트를 취소해야한다 생각합니다.

protected void ods_Selecting(object sender, 
       ObjectDataSourceSelectingEventArgs e) 
{ 
     if (e.ExecutingSelectCount) 
     { 
      //Cancel the event 
      return; 
     } 
} 

이 도움이 http://www.unboxedsolutions.com/sean/archive/2005/12/28/818.aspx

희망 아래 링크에서 언급 한 바와 같이 당신은 완전한 이행을 찾아보실 수 있습니다.

+0

SelectCountMethod가 제공되면 select를 호출해서는 안됩니다. 위의 경우, 자식 컨트롤을 생성하는 동안 포스트 백에서 두 번, 프리 렌더링에서 두 번 호출됩니다. – Ruslan

+0

@Ruslan : 디버그하면 ods_Selecting 이벤트가 두 번 치게됩니다. – dhinesh

+0

여기에 약간의 혼란이 있습니다. 내'SelectMethod'는'SelectCountMethod'가 사용하는 카운트를 캐쉬하기 때문에, DB는 그 이유 때문에 두 번 히트되지 않습니다. 'SelectMethod','SelectCountMethod' 및'OnSelecting' 이벤트가 있습니다. 일반적으로 (** ViewState가 가능 **),'SelectMethod'와'SelectCount' 메쏘드는 ** once **라고 불립니다. 'OnSelecting'은 ** e.ExecutingSelectCount = false'와 함께 한 번, ** e.ExecutingSelectCount = true'와 함께 ** 두 번 ** ** 호출됩니다. ** ViewState가 비활성화되면 **,'SelectMethod' 및'SelectCountMethod'는 ** ** ** 두 번 호출됩니다. 'OnSelecting'은 ** 네 번 호출됩니다 **. –

0

브라우저마다 다르게 작동하는 비슷한 문제가있었습니다. IE 편도 및 다른 모든 브라우저 편도 .. 당신과 같은 문제가 아닐 수도 있습니다.

나는 그것을 이런 식으로 해결 :

 protected void DropDownDataBound(object sender, EventArgs e) 
    { 
     // Issue with IE - Disable ViewState for IE browsers otherwhise the dropdown will render empty. 
     DropDownList DDL = (DropDownList)sender; 
     if (Request.Browser.Browser.Equals("IE", StringComparison.CurrentCultureIgnoreCase)) 
      DDL.ViewStateMode = System.Web.UI.ViewStateMode.Disabled; 
     else 
      DDL.ViewStateMode = System.Web.UI.ViewStateMode.Inherit;   
    } 
+0

광산에서 항상 렌더링 (비어 있지 않음)하고 브라우저는이 경우에 차이를 만들지 않습니다. –

관련 문제