2009-06-24 1 views
1

У меня возникли некоторые вопросы, получить метод .Filter() работать в дозвуковой, и я постоянно получаю ошибки, как показано ниже:SubSonic .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; 
    } 

И SubSonic 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 вы можете просто сделать это с помощью лямбда-функции:

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

Привет Адам, Хотя это действительно просто приложение клиентов в 2,0 – Doug

0

Фильтр предназначен для работы над коллекцией - это «objNavigation» коллекция? Проблема, с которой вы столкнулись, заключается в том, что критерии Filter() не могут быть удовлетворены с именем столбца «NavHigherID».

+0

, что проблема - objNavigation это сборник «NavCollection», состоящий из «Nav» Я подумал, что, возможно, я использовал его неправильно - я правильно использую «.WHERE(). Filter()« взамен ».WHERE(). LOAD() "?? и будет ли фильтр FURTHER фильтровать коллекцию или добавлять элементы в базовую целую коллекцию и начинать заново? заранее заранее – Doug

+0

О, да, я думаю, вы ударили его. Попробуйте использовать Where (...). Load(), чтобы сначала загрузить список, затем используйте Filter(). Это должно сделать это ... –

+0

Привет. Следующий код по-прежнему не удается с NullReferenceException (последний есть только так я могу видеть его в отладчике) NavCollection objFullCollection = новый NavCollection() Load(). NavCollection objTopLevel = objFullCollection.Where (Nav.Columns.NavHigherID, 0) .Filter(); NavCollection objFinalCol = objTopLevel; – Doug

0

У меня был такой же Prob, попробуйте сделать свой фильтр, как это:

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

К сожалению, у меня все еще есть точно такая же проблема.я тестировал даже с простой загрузкой коллекции, а затем загружал ее в другую коллекцию, где() и фильтр (даже делая именно это) и «pi» в методе фильтра всегда равны нулю. Неужели все уверены, что это не ошибка? кто-нибудь его протестировал, и если да, у меня есть пример кода рабочего бита кода? – Doug

Смежные вопросы