Question

J'ai des problèmes pour que la méthode .Filter () fonctionne en subsonic, et je reçois constamment des erreurs telles que celle ci-dessous:

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

Je fais des appels comme celui ci-dessous - est-ce la bonne façon de l'utiliser? Il semble n'y avoir aucune documentation sur l'utilisation de cette méthode

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

merci d'avance

Était-ce utile?

La solution

La valeur que vous filtrez doit être le nom de la propriété, pas le nom de la colonne de la base de données.

Vous pouvez essayer ceci:

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

Ou voici une méthode légèrement plus détaillée qui fonctionne pour moi en fonction des remplacements personnalisés de la méthode .Filter (). Cela semblait mieux fonctionner (du moins pour moi) en créant explicitement le Où précédemment:

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

Voici les substitutions:

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

Et SubSonic 2.0 ne prend pas réellement en charge In / NotIn pour la fonction IsMatch. Voici donc la version personnalisée qui le fait (dans 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;
    }

Autres conseils

SI vous utilisez .net 3.5, vous pouvez le faire avec une fonction lambda:

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

Le filtre est conçu pour fonctionner sur une collection - est "objNavigation". une collection? Le problème que vous rencontrez est que les critères de Filter () ne peuvent pas être satisfaits avec le nom de colonne "NavHigherID".

J'avais le même problème, essayez de faire votre filtre comme ceci:

lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top