内存滤波器中的 SubSonic .Filter()

发布于 2024-07-25 06:09:18 字数 695 浏览 10 评论 0原文

我在使 .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();

提前致谢

i'm having some issues getting the .Filter() method to work in subsonic, and i'm constantly getting errors like the one below:

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 making calls like the one below- is this the corrent way to use it? There seems to be no documentation on the use of this method

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

thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

罗罗贝儿 2024-08-01 06:09:18

您筛选的值必须是属性名称,而不是数据库列名称。

您可以尝试以下方法:

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实际上并不支持IsMatch函数的In/NotIn,所以这里是定制的版本(在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;
    }

The value you filter against needs to be the Property Name, not the database column name.

You might try this:

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

Or here's a slightly more verbose method that works for me based on custom overrides of the .Filter() method. It seemed to work better (for me at least) by explicitly creating the Where beforehand:

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

Here's the overrides:

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

And SubSonic 2.0 doesn't actually support In/NotIn for the IsMatch function, so here's the customized version that does (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;
    }
风尘浪孓 2024-08-01 06:09:18

如果您使用 .net 3.5,您可以使用 lambda 函数来完成此操作:

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

IF you're using .net 3.5 you could just do this with a lambda function:

NavCollection objTopLevelCol = 
  objNavigation.Where(nav => nav.NavHigherID == 0);
百善笑为先 2024-08-01 06:09:18

过滤器设计用于处理集合 - “objNavigation”是集合吗? 您遇到的问题是列名“NavHigherID”无法满足 Filter() 的条件。

Filter is designed to work on a collection - is "objNavigation" a collection? The problem you're running into is that the criteria for Filter() can't be met with the column name "NavHigherID".

小苏打饼 2024-08-01 06:09:18

我遇到了同样的问题,尝试像这样进行过滤:

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

I was having same prob, try doing your filter like this :

lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文