Searching a List (ReadOnly or Editable)

Searching a List (ReadOnly or Editable)

Old forum URL: forums.lhotka.net/forums/t/1604.aspx


boo posted on Thursday, October 26, 2006

I'm currently transferring some code to CSLA; one thing that's been bugging me as I go along is handling the following situation:

The current 'business objects' that are being replaced are simple objects (just data, no rules), that have methods such as:

public static ObjectX FindXByWhatever(string var1, List<ObjectX> listOfX)
{
       Predicate<ObjectX> handler = delegate(ObjectX test)
       {
               return test.StrProp = = var1;
       };
       return  listOfX.Find(handler);
}

These methods are called from Business Layer objects that need to get a subset of an entire collection for whatever reasons when doing business processing.

So with the new CSLA based business objects I've really been struggling to decide whether to have several factory methods such as:

GetListOfX(string filter)
GetListOfX(int arg1, int arg2)
GetListOfX(int arg1, string arg2)
GetXById(int id)
GetXByPropY(double y)
GetXBySomethingElse(int arg1, AnotherObject obj)

add nauseum...

This approach has lead to having multiple DataPortal_Fetch(Criteria x) methods...each with a different criteria and passes different parameters to existing stored procedures (as is done in several of the current DAC methods), or using a criteria class that has properties that may not be needed depending on the factory method called (again passing different parameters to the same stored procedure) - and some of my criteria are derived criteria of a parent criteria (to avoid unneeded criteria properties)...it's a real mess and it works, but, I don't really 'feel' like it's correct CSLA and I can't stand to look at it, so I know something isn't right.

My other alternative I've been toying with is to keep my factory 'GetList' a single method, then having business methods that are similar to the original implementation, except instead of being static and having to past the generic list in, they are instance methods that work against the internal Items collection...basically it has the same results but this doesn't seem to be in the spirit of the CSLA either.

And then of coarse there's the composite of the two, several factory methods, but instead of using serveral DataPortal_Fetch methods, filtering the list as I do above with the generics against a single return from a Fetch call.

I'm not sold on any of these approaches being the best, but I'm not sure what the 'ideal' solution is.   I'm sure others have come across these type of situations so I'm hoping for some good advise.

Also will the next version of CSLA maybe have the internal Items property of the 'List' business objects be similiar to the List<T> object with built in Find, FindAll, ForEach, etc...or maybe even inherit from List<T> if it's possible?  This would make writing anonymous delegate for on the fly searches easier...but then maybe doing this isn't the best way to do things with the CSLA - still too new to the CSLA to know the answer to those type of things.

Thanks!

ajj3085 replied on Friday, October 27, 2006

This has been addressed many times before.  You may want to search on this forum, starting with this thread.

Brian Criswell replied on Friday, October 27, 2006

The ListBase classes inherit from BindingList<T>.  Rocky just did not provide a default FindCore() implementation.  You could also look at FilteredBindinglist or ObjectListView, both of which provide a filtered list of your objects.  This allows you to have a minimum of list fetch methods.  Instead you provide your filter criteria to the filter which returns a reduced set of items, much like a DataView does with a DataTable.

JoeFallon1 replied on Friday, October 27, 2006

I use Brian's ObjectListView because it is so versatile. It does sorting and filtering. Plus it does multi-column sorting. It is a nice piece of code.

If you use it for filtering then you have to fetch "large" collections in your BO lists and then let the user filter them dynamically.

The alternative is to add methods like you have described, let the DB return a smaller set of records and skip filtering in the UI.

Many of us have built special classes to gather up filtering data and then dynamically build a WHERE clause and return the smaller result set. This means you add 1 Shared method to your list which accetps this special class as the Type.  You can bind a Search form to this class and then on Submit, gather up the values and pass yourself to the list as the filtered criteria, build the SQL and return a small list.

Joe

 

Copyright (c) Marimer LLC