2009-06-24 150 views
1

我遇到一些問題得到.Filter()方法在亞音速工作,我經常收到這樣的錯誤下一個存儲過濾器:亞音速.Filter()在

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.  

Line 36:      bool remove = false; 
Line 37:      System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName); 
Line 38:      if (pi.CanRead) 
Line 39:      { 
Line 40:       object val = pi.GetValue(o, null); 

我」 m打電話就像下面這樣 - 這是使用它的方式嗎?人們似乎在利用這種方法沒有文件事先

  NavCollection objTopLevelCol = objNavigation.Where(Nav.Columns.NavHigherID,Comparison.Equals, 0).Filter(); 

感謝

回答

2

您篩選對需求的值是屬性名稱,而不是數據庫列名。

你可以試試這個:

lCol = objNavigation.Where(Nav.HigherIDColumn.PropertyName,Comparison.Equals, 0).Filter(); 

還是這裏的,基於.Filter()方法的自定義的替換對我的作品稍微更詳細的方法。看來(至少對我來說)通過明確創建凡事先更好地工作:

SubSonic.Where w = new SubSonic.Where(); 
    w.ColumnName = Nav.HigherIDColumn.PropertyName; 
    w.Comparison = SubSonic.Comparison.NotIn; 
    w.ParameterValue = new string[] { "validvalue1", "validvalue2" }; 

    lCol = objNavigation.Filter(w, false); 

這裏的覆蓋:

/// <summary> 
    /// Filters an existing collection based on the set criteria. This is an in-memory filter. 
    /// All existing wheres are retained. 
    /// </summary> 
    /// <returns>NavCollection</returns> 
    public NavCollection Filter(SubSonic.Where w) 
    { 
     return Filter(w, false); 
    } 

    /// <summary> 
    /// Filters an existing collection based on the set criteria. This is an in-memory filter. 
    /// Existing wheres can be cleared if not needed. 
    /// </summary> 
    /// <returns>NavCollection</returns> 
    public NavCollection Filter(SubSonic.Where w, bool clearWheres) 
    { 
     if (clearWheres) 
     { 
      this.wheres.Clear(); 
     } 
     this.wheres.Add(w); 
     return Filter(); 
    } 

    /// <summary> 
    /// Filters an existing collection based on the set criteria. This is an in-memory filter. 
    /// Thanks to developingchris for this! 
    /// </summary> 
    /// <returns>NavCollection</returns> 
    public NavCollection Filter() 
    { 
     for (int i = this.Count - 1; i > -1; i--) 
     { 
      Nav o = this[i]; 
      foreach (SubSonic.Where w in this.wheres) 
      { 
       bool remove = false; 
       System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName); 
       if (pi != null && pi.CanRead) 
       { 
        object val = pi.GetValue(o, null); 
        if (w.ParameterValue is Array) 
        { 
         Array paramValues = (Array)w.ParameterValue; 
         foreach (object arrayVal in paramValues) 
         { 
          remove = !Utility.IsMatch(w.Comparison, val, arrayVal); 
          if (remove) 
           break; 
         } 
        } 
        else 
        { 
         remove = !Utility.IsMatch(w.Comparison, val, w.ParameterValue); 
        } 
       } 


       if (remove) 
       { 
        this.Remove(o); 
        break; 
       } 
      } 
     } 
     return this; 
    } 

而且亞音速2.0實際上並不支持/ NotIn爲IsMatch功能,所以這裏的定製版本,做(亞音速\ Utility.cs):亞當

public static bool IsMatch(SubSonic.Comparison compare, object objA, object objB) 
    { 
     if (objA.GetType() != objB.GetType()) 
      return false; 

     bool isIntegerVal = (typeof(int) == objA.GetType()); 
     bool isDateTimeVal = (typeof(DateTime) == objA.GetType()); 

     switch (compare) 
     { 
      case SubSonic.Comparison.In: 
      case SubSonic.Comparison.Equals: 
       if (objA.GetType() == typeof(string)) 
        return IsMatch((string)objA, (string)objB); 
       else 
        return objA.Equals(objB); 
      case SubSonic.Comparison.NotIn: 
      case SubSonic.Comparison.NotEquals: 
       return !objA.Equals(objB); 
      case SubSonic.Comparison.Like: 
       return objA.ToString().Contains(objB.ToString()); 
      case SubSonic.Comparison.NotLike: 
       return !objA.ToString().Contains(objB.ToString()); 
      case SubSonic.Comparison.GreaterThan: 
       if (isIntegerVal) 
       { 
        return ((int)objA > (int)objB); 
       } 
       else if (isDateTimeVal) 
       { 
        return ((DateTime)objA > (DateTime)objB); 
       } 
       break; 
      case SubSonic.Comparison.GreaterOrEquals: 
       if (isIntegerVal) 
       { 
        return ((int)objA >= (int)objB); 
       } 
       else if (isDateTimeVal) 
       { 
        return ((DateTime)objA >= (DateTime)objB); 
       } 
       break; 
      case SubSonic.Comparison.LessThan: 
       if (isIntegerVal) 
       { 
        return ((int)objA < (int)objB); 
       } 
       else if (isDateTimeVal) 
       { 
        return ((DateTime)objA < (DateTime)objB); 
       } 
       break; 
      case SubSonic.Comparison.LessOrEquals: 
       if (isIntegerVal) 
       { 
        return ((int)objA <= (int)objB); 
       } 
       else if (isDateTimeVal) 
       { 
        return ((DateTime)objA <= (DateTime)objB); 
       } 
       break; 
     } 
     return false; 
    } 
1

如果你使用.NET 3.5,你可能只是這樣做有一個lambda函數:

NavCollection objTopLevelCol = 
    objNavigation.Where(nav => nav.NavHigherID == 0); 
+0

嗨,雖然這是非常簡單的客戶端應用程序是在2.0 – Doug 2009-09-22 05:34:31

0

過濾器設計用於集合 - 是「objNavigation」集合嗎?您遇到的問題是無法通過列名「NavHigherID」滿足Filter()的條件。

+0

這就是問題所在 - objNavigation是一個由「Nav」組成的「NavCollection」集合 我以爲也許我錯誤地使用了它 - 我是否正確使用「.WHERE().Filter()」替代了「.WHERE()」。 LOAD()「?? 並將過濾器FURTHER過濾器集合或添加到底座全集合並重新啓動? 在此先感謝 – Doug 2009-06-25 13:17:03

+0

哦 - 是的,我認爲你打它。嘗試使用Where(...)。Load()首先加載列表 - 然後使用Filter()。這應該做到這一點... – 2009-06-25 19:08:49

0

我有相同的概率,嘗試做你的過濾器是這樣的:

lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();