views:

204

answers:

2

Embarrassing question really -- I have Subsonic collection, then I filter out some data using Where.

MyColl.Where(it => it.foo()==true)

now I would like to pass those data still as Subsonic collection. How to do it (the most properly way)? I checked constructor for Subsonic collection, ToX() methods, and googled.

edit: Subsonic 2.x series.

Thank you in advance, and sorry for naive question.

+2  A: 

In SubSonic 2.x, the data isn't actually filtered out with Where() until the query is re-executed against the database. I'm assuming that's the same in 3.0. In 2.x there was a .Filter() method that would do what you are looking for.

The .Filter() method gets added to the generated classes. Here's what mine looks like (it's customized from the default):

    /// <summary>
    /// Filters an existing collection based on the set criteria. This is an in-memory filter.
    /// All existing wheres are retained.
    /// </summary>
    /// <returns>TblSomethingOrOtherCollection</returns>
    public TblSomethingOrOtherCollection 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>TblSomethingOrOtherCollection</returns>
    public TblSomethingOrOtherCollection 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>TblSomethingOrOtherCollection</returns>
    public TblSomethingOrOtherCollection Filter()
    {
        for (int i = this.Count - 1; i > -1; i--)
        {
            TblSomethingOrOther 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;
    }


}
ranomore
Thank you for pointing out version, I forgot to mention it it is 2.x series. I don't see Filter method.
macias
@macias - sorry for the delay in responding! I added a code sample.
ranomore
+1  A: 

For some reason i could never get the inline method of filter to work, but its easy to use like this:

 SubSonic.Where w = new Where();
        w.ColumnName = Product.CatIDColumn.PropertyName;
        w.Comparison = Comparison.Equals;
        w.ParameterValue = "1";

 ProductCollection objFilteredCol = objProdCollection.Where(w).Filter();
Doug
Thank you, it is clear from your examples (yours and Ranomore's) that I need at least slight upgrade of Subsonic :-)
macias