2009-06-24 5 views
1

ich bin einige Probleme mit der .Filter() -Methode immer in Unterschall zu arbeiten, und ich bin immer wieder Fehler wie die unten bekommen:SubSonic .Filter() in Speicherfilter

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); 

i‘ m wie unten zu telefonieren - ist das der richtige Weg, es zu benutzen? Es scheint sich auf die Anwendung dieser Methode

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

Dank im Voraus keine Dokumentation zu sein

Antwort

2

Der Wert, den Sie gegen Bedarf filtern der Name, nicht die Datenbank Spaltennamen zu sein.

Sie könnten versuchen, diese:

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

Oder hier ist eine etwas ausführlichere Methode, basierend auf benutzerdefinierten Überschreibungen der .Filter() Methode funktioniert für mich. Es schien besser zu arbeiten (für mich zumindest), indem Sie explizit die Wo vorher erstellen:

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); 

Hier ist die Überschreibungen:

/// <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; 
    } 

Und SubSonic 2.0 nicht wirklich in/Notin Unterstützung für die IsMatch Funktion, also hier die angepasste Version, die funktioniert (in SubSonic \ 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

WENN Sie .net verwenden sind 3,5 Sie gerade dies mit einer Lambda-Funktion tun könnte:

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

Hallo Adam, Während dies wirklich einfach ist die Kunden-Anwendung in 2,0 – Doug

0

Filter ist entworfen, um an einer Sammlung zu arbeiten - ist "objNavigation" eine Sammlung? Das Problem besteht darin, dass die Kriterien für Filter() nicht mit dem Spaltennamen "NavHigherID" erfüllt werden können.

+0

ist, dass das Problem ist - objNavigation ist eine Sammlung "NavCollection" bestehend aus "Nav" ich dachte, dass ich es vielleicht falsch verwendet habe - bin ich richtig in meiner Verwendung von ".WHERE(). Filter()" als Ersatz für ".WHERE(). BELASTUNG()" ?? und wird der Filter WEITER Filtere die Sammlung oder fügen Sie Wheres zur Basis ganze Sammlung und starten Sie erneut? danke im voraus – Doug

+0

Oh - ja ich denke du hast es geschafft. Versuchen Sie Where (...). Load() zu verwenden, um die Liste zuerst zu laden - benutzen Sie dann Filter(). Das sollte es tun ... –

+0

Hallo nochmal. Der folgende Code schlägt immer noch mit einer NullReferenceException fehl (die letzte ist nur vorhanden, damit ich sie im Debugger sehen kann) NavCollection objFullCollection = new NavCollection(). Load(); NavCollection objTopLevel = objFullCollection.Where (Nav.Column.NavHigherID, 0) .Filter(); NavCollection objFinalCol = objTopLevel; – Doug

0

ich gleiche prob hatte, versuchen Sie einen Filter, wie dies zu tun:

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

Leider habe ich immer noch genau das gleiche Problem.Ich habe sogar mit dem einfachen Laden einer Sammlung getestet, und dann laden Sie es in eine andere Sammlung mit Where() und Filter (auch genau das oben) und die "Pi" in der Filtermethode ist immer Null. Ist jeder sicher, dass dies kein Fehler ist? Hat jemand es getestet und wenn ja, kann ich ein Code-Beispiel für ein funktionierendes Bit Code haben? – Doug