2011-07-29 1 views
1

시스템 관리자를위한 간단한 엔티티 관리 콘솔로 EF POCO ObjectContext와 함께 ASP.NET Dynamic Data 4.0을 사용하고 싶습니다. (이 기술을 포기할 것을 고려하고 있습니다 ...).ASP.NET 동적 데이터 필터링

삽입/업데이트 작업이 있습니다.

내장 데이터가 쓸모 없기 때문에 추가 데이터 형식에 필터를 추가하는 방법을 알아 냈습니다. QueryableFilterRepeater가 필터링으로 내 열을 노출하는 방법을 알아낼 수 없습니다. 모든 적용 가능한 유형에 FilterUIHints를 추가 할 수 없으므로 수용할만한 솔루션이 아닙니다. 내장 된 Entity Framework 메타 데이터 모델 공급자를 활용하고 싶습니다. 나는 내 자신을 쓰고 싶지 않아. 이 문제는 QueryableFilterIterator가 MetaTable.GetFilteredColumns()를 호출하고 bool/int/DateTime 열 (쓸모없는) 만 반환한다는 사실에 기인합니다.

ASP.NET 동적 데이터 필터링 (http://dynamicdatafiltering.codeplex.com/)을 체크 아웃했지만 4.0 용으로 유지 관리되지 않는 것 같습니다.

  1. 이 (필터링으로 내 열을 얻을) 할 수있는 방법이 있나요 :

    가 나는 두 가지 질문이 됐을까?

  2. 다이내믹 데이터는 실제로 실제 세계에서 사용하기에 적합합니까?
+1

어쩌면 이것이 도움이 될지 모른다. [정의 필터] [1] http://stackoverflow.com/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template [1]에 http : // 유래. co.kr/questions/3612777/asp-net-dynamic-data-textsearch-custom-filter-template – GermanSniper

답변

1

실망스럽고 직접적인 경로를 취했습니다. 이보다 더 좋은 해결책이 없다면 마이크로 소프트는이 일에 정말로 열악한 업무를 수행했다.

public class QueryableFilterRepeater : System.Web.DynamicData.QueryableFilterRepeater 
    { 
     private static readonly FieldInfo FiltersField = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetField("_filters", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly FieldInfo DataSourceField = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetField("_dataSource", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly MethodInfo FilterInitializeMethod = typeof(DynamicFilter).GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic); 
     private static readonly PropertyInfo FilterContextProperty = typeof(DynamicFilter).GetProperty("Context", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); 
     private static readonly MethodInfo PageInitCompleteMethod = typeof(System.Web.DynamicData.QueryableFilterRepeater).GetMethod("Page_InitComplete", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); 
     private static readonly EventInfo InitCompleteEvent = typeof(Page).GetEvent("InitComplete"); 

     private readonly List<DynamicFilter> filters; 
     private int filterCount; 
     private bool initialized; 

     public IEnumerable<DynamicFilter> Filters 
     { 
      get { return filters; } 
     } 

     public QueryableFilterRepeater() 
     { 
      filters = (List<DynamicFilter>)FiltersField.GetValue(this); 
     } 

     private IQueryableDataSource DataSource 
     { 
      get { return DataSourceField.GetValue(this) as IQueryableDataSource; } 
     } 
     protected override void OnInit(EventArgs e) 
     { 
      base.OnInit(e); 

      InitCompleteEvent.RemoveEventHandler(Page, Delegate.CreateDelegate(typeof(EventHandler), this, PageInitCompleteMethod)); 

      Page.InitComplete += new EventHandler(Page_InitComplete); 
     } 

     protected override void OnLoad(EventArgs e) 
     { 
      filters.Select((f, i) => new { f, i }).Where(x => x.i > filterCount - 1).ToList().ForEach(x => filters.Remove(x.f)); 
      Controls.OfType<Control>().Select((c, i) => new { c, i }).Where(x => x.i > filterCount - 1).ToList().ForEach(x => Controls.Remove(x.c)); 
      base.OnLoad(e); 
     } 

     private void Page_InitComplete(object sender, EventArgs e) 
     { 
      if (!initialized) 
      { 
       Controls.Clear(); 
       filters.Clear(); 

       MetaTable metaTable = DataSource.GetMetaTable(); 
       int num = 0; 
       foreach (MetaColumn column in metaTable.Columns) 
       { 
        string filterUIHint = GetFilterUIHint(column); 
        if (filterUIHint == null) continue; 

        var filterRepeaterItem = new FilterRepeaterItem(); 
        filterRepeaterItem.DataItemIndex = num; 
        filterRepeaterItem.DisplayIndex = num; 
        FilterRepeaterItem container = filterRepeaterItem; 
        num++; 
        ItemTemplate.InstantiateIn(container); 
        Controls.Add(container); 
        var dynamicFilter = container.FindControl(DynamicFilterContainerId) as DynamicFilter; 
        if (dynamicFilter == null) 
        { 
         throw new InvalidOperationException(); 
        } 
        FilterContextProperty.SetValue(dynamicFilter, new HttpContextWrapper(Context), null); 
        dynamicFilter.DataField = column.Name; 
        container.DataItem = column; 
        container.DataBind(); 
        container.DataItem = null; 

        dynamicFilter.FilterUIHint = filterUIHint; 
        filters.Add(dynamicFilter); 
        filterCount++; 
       } 
       filters.ForEach(f => FilterInitializeMethod.Invoke(f, new[] { DataSource })); 
       initialized = true; 
      } 
     } 

     private string GetFilterUIHint(MetaColumn column) 
     { 
      if (GetUnderlyingType(column.ColumnType) == typeof(string)) 
      { 
       return "String"; 
      } 
      if (GetUnderlyingType(column.ColumnType) == typeof(bool)) 
      { 
       return "Boolean"; 
      } 
      if (GetUnderlyingType(column.ColumnType).IsEnum) 
      { 
       return "Enumeration"; 
      } 
      if (GetUnderlyingType(column.ColumnType) == typeof(DateTime)) 
      { 
       return "DateTime"; 
      } 
      if (column is MetaForeignKeyColumn) 
      { 
       return "ForeignKey"; 
      } 
      if (column is MetaChildrenColumn) 
      { 
       return "Children"; 
      } 

      return null; 
     } 

     private Type GetUnderlyingType(Type type) 
     { 
      return Nullable.GetUnderlyingType(type) ?? type; 
     } 

     // Nested Types 

     #region Nested type: FilterRepeaterItem 

     private class FilterRepeaterItem : Control, IDataItemContainer 
     { 
      // Properties 

      #region IDataItemContainer Members 

      public object DataItem { get; internal set; } 
      public int DataItemIndex { get; internal set; } 
      public int DisplayIndex { get; internal set; } 

      #endregion 
     } 

     #endregion 
    }