Вопрос

у меня возникли проблемы с работой метода .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);

я совершаю звонки, как показано ниже. Это правильный способ использования?Кажется, нет документации по использованию этого метода.

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

заранее спасибо

Это было полезно?

Решение

Значение, по которому вы фильтруете, должно быть именем свойства, а не именем столбца базы данных.

Вы можете попробовать это:

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

Или вот более подробный метод, который работает для меня на основе пользовательских переопределений метода .Filter (). Казалось, что он работает лучше (по крайней мере, для меня), явно создавая Where заранее:

    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 на самом деле не поддерживает In / NotIn для функции IsMatch, поэтому вот настроенная версия, которая поддерживает (в 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;
    }

Другие советы

Если вы используете .net 3.5, вы можете просто сделать это с помощью лямбда-функции:

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

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

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

lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top