How do I filter a business object by a custom property?


Author
Message
Trent Taylor
Trent Taylor
StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
Bill,

I think that you are trying to make this too complicated.  I think that I would first backup and then start rethinking through your process.

First, we use custom columns as aggregates OR create a custom property that dynamically returns aggregates a lot.  Now since you are trying to apply a filter, then you will most likely want a column in the data table.

OK.  Since we have that established, from what I can understand, you always want to have a calculated column within your data table.  So obviously if you perform a query, then you can do this as part of the query (easier and faster in some cases).  However, if you will have a scenario that will not retrieve data from a database query first, then you would need to ensure that the column gets manually added prior to being refrenced or accessed.  So in this case, I would do one of two things to ensure that the column exists within the BO.

  1. Override the OnAfterAddNew method of the BO and ensure that the desired columns get added within the BO and/or exist when a new record is added.  This way a query is not required, but when you add a new record the BO will ensure that the column exists.
  2. Override the OnCurrentDataTableRefilled method of the BO and call the same logic that is added as part of the OnAfterAddNew method.

By doing the above two things you will always be ensured that you have the column within your data table, thus allowing a filter to be applied.

At this point, you will just create the custom property on the BO to access it through the strong-typed reference, but you can then treat this column just as though you could any other column that comes from the database, however, it just resides within the BO.

Greg McGuffey
Greg McGuffey
Strategic Support Team Member (2.8K reputation)
Group: Forum Members
Posts: 2K, Visits: 6.6K
Some more thoughts (do I smell something burning?)....Tongue



The second option is basically the first, just using a method to do the walking and loading, rather than the custom property...probably won't be any good in your situation either. I'd also try to find out why it takes so long...maybe there is something you could do to speed it up. Unless the data set is very large and/or the computation very complicated, this should be fast.



For the third option, if you are using SQL Server 2005, consider a CLR sproc. You program in the .NET language of choice (C# for you I believe) and they tend to be fast. You likely could get a several minute process down to milliseconds. Search the forum for CLR stored procedures, there are some good posts about them by the SF team. While I agree that placing code in BOs is the way to go, when I need speed for a data intensive process, I use SQL Server. Now, sometimes, I can get the SQL Server joy AND put the code in the BO. That command object can accept any sort of SQL. I.e. you can do the work on SQL server but put the code (SQL script) in your BO. This won't be as fast as a sproc (the execution plan isn't precompiled and cached on SQL Server), but might do the trick.



If your custom properties aren't showing up, my first guess would be that you forgot to setup the custom property descriptors, but I'm still a newbie when it comes to grids so not sure if they are used in that case... Sad



Good luck and remember to wear your fire retardant pants! w00t
Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
Fascinating.  Bewildering.  Frustrating.

There are three custom properties and one additional column (for the filter).  Prop3 = Prop2 - Prop1 (basically), then ColumnA = Prop3.  Filter ColumnA so that only values greater than 0 are shown.

in your fill method, you could loop through the BO and fill the column by accessing the custom property

Looping through the BO is very time consuming...several minutes to kerchunk each custom prop, then display the grid.  Not a good option.  In addition, the filter did not work even though the column has data!  It shows on the grid.  None of the custom properties show up on the grid...all blank still.

use a method that would fill that column (after adding it) (rather than using the custom property).

That seems to only affect the first row of the BO. 

Both of these last two options made the BO dirty.  Closing the window asked me if I want to save changes.

have SQL do the work and return that column

This is an option (and I have done this for several other BOs)...but, the complexity of the stored procs and UDFs would make the process so slow and painful that it just isn't fun anymore.  Placing the complex code inside of custom class and/or business object really, really makes things a LOT easier (cleaner and neater, too). 

Well, back to the drawing board.  And, in the immortal words of Bill the Cat:

ACK!

Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
The fire is already crackling loudly under my feet.  I'll go through those ideas in no particular order.  Smile

Thanks a ton, Greg!
Bill

Greg McGuffey
Greg McGuffey
Strategic Support Team Member (2.8K reputation)
Group: Forum Members
Posts: 2K, Visits: 6.6K
Well, you need to have data in the colReqQty for the filter to work, but your only filling it if/when the custom property is being accessed. Time to rethink this, I'd think Wink



Here are some ideas (in no particular order):

- in your fill method, you could loop through the BO and fill the column by accessing the custom property

- use a method that would fill that column (after adding it) (rather than using the custom property).

- have SQL do the work and return that column



Just do this before you set the filter.



Hope this sparks some ideas (without starting a fire! Blink )
Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
If I put a break on the first line of the code in the custom property, then run the app and open the window that uses the BO, the code NEVER hits this line:

decimal mReqQty = (this.minstocklevel - this.onhandqty) + (this.spxSalesOrderQty - this.spxWorkOrderQty);

What am I doing wrong?  Since the actual custom property is not getting "filled" then the value of my additional column will never get updated.  Therefore, my filter will not work.

This is just viscious! 

BigGrin  <--- see I am still smiling!!

Perhaps I did not get enough sleep last night.


Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
I added the code below into the CurrentDataTableRefilled method:

CurrentDataTable.Columns.Add("colReqQty", typeof(decimal));

I am checking for the existence before adding.  I then set a filter on the BO to something like this:

MyBO.Filter = "colReqQty > 0";

Nothing.  As a matter of fact, I am getting no value for my Custom Property, at all (named "spxRequiredQty").  Here is my code for the custom property:


public decimal spxRequiredQty
{
   
get
   
{
       
decimal mReqQty = (this.minstocklevel - this.onhandqty) + (this.spxSalesOrderQty - this.spxWorkOrderQty);
       
if (mReqQty < 0) mReqQty = 0;
       
this["colReqQty"] = mReqQty;
       
return mReqQty;
    }
}

I should be able to see a column called [colReqQty] in my BO; however, it does not show up.  For example, I cannot add it to a grid via a BBS.

At the moment, I am quite confused.

Blink


Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
Thanks, Trent!

Man, I am getting tired...past midnight here.  Still struggling with this, though.  Looks like I will have to get back to this later.  Gotta sleep.

No Mountain Dew in the house.  Wink

I'll get back with you "tomorrow."
Bill

Trent Taylor
Trent Taylor
StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
You would just want to reference the Item property of the BO or the Item property of the CurrentDataTable.  The example above is just talking to the BO default property which is the Item collection.  When dealing with a default property, you can access on the root of the object like this:

this["MyAggregateField"] = 1 + 1;

or you could talk straight to the current row:

this.CurrentRow["MyAggregateField"] = 1 + 1;

Bill Cunnien
Bill Cunnien
StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)StrataFrame VIP (1K reputation)
Group: Forum Members
Posts: 785, Visits: 3.6K
...or in the CurrentDataRefilled event of your BO, you could progammatically add the columns into the CurrentDataTable so that you could filter on this as well:

CurrentDataTable.Columns.Add("MyAggregateField",GetType(Integer))

You could then, in your custom property, store off the value in the Set (or even the Get of the proper if it is readonly):

<Add standard attributes>
Public Readonly Property MyCustomProperty As Integer
   Get
      Me.Item("MyAggregateField") = 1 + 1
      Return CType(me.Item("MyAggregateField"), Integer)
   End Get
End Property

Taking this approach you could then sort and filter on the aggregate field.

Took a while for me to readdress this issue.  I am hitting another brick wall.  I tried adding the column in the method.  If I run a search on the BO, the CurrentDataTable gets refilled again and the column is tried to be readded.  Pop!  Error.  So, I'll check for existence of the column before adding it.

Also, setting the aggregate field to the value of the custom property is tripping me up.  Your VB "Me.Item("MyAggregateField")" is not translating for me in my C# world.  Please let me know where I can access that collection(?). 

Thanks!!
Bill

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search