| | | StrataFrame User
       
Group: StrataFrame Users Last Login: Yesterday @ 6:32:47 PM Posts: 349, Visits: 1,205 |
| | When I attempt to filter a BO on a custom property, the debugger tells that the specified column does not exist. It is true that it cannot be found in the DB, but it is on the BO. Is there a trick to filtering on a custom property? Thanks, Bill |
| | | | 
StrataFrame Developer

Group: StrataFrame Developers Last Login: Today @ 8:47:41 AM Posts: 4,104, Visits: 4,175 |
| You cannot filter on a custom property as this property does not exist in the CurrentDataTable. The Filter and Sort properties just pass this on to the CurrentDataTable.DefaultView (or MyBO.CurrentView). So if the DataView cannot see the field it will give you this error. You have to filter or sort on a logical field. Hope that helps |
| | | | StrataFrame User
       
Group: StrataFrame Users Last Login: Yesterday @ 6:32:47 PM Posts: 349, Visits: 1,205 |
| Trent L. Taylor (01/28/2008) You cannot filter on a custom propertyNot good. In another post today, I explored the issue of limiting my data being presented to the user because of bandwidth constraints. One way for me to do this easily would be to simply set a filter on one of the custom properties of the BO. Since I cannot do this, my problem has become gargantuan. Since the property is there, there must be a way to do this kind of filtering. I cannot give up, yet. Let me make sure I get this....if I had a customer business object with a really cool custom property like TotalOrders, it is impossible for me using that custom property to display all customers with more than 100 orders. Is that right? |
| | | | StrataFrame VIP
       
Group: StrataFrame Users Last Login: Yesterday @ 7:28:28 PM Posts: 1,148, Visits: 2,830 |
| Let me make sure I get this....if I had a customer business object with a really cool custom property like TotalOrders, it is impossible for me using that custom property to display all customers with more than 100 orders. Is that right?
It depends... It really has nothing to do with the custom property, but everything to do with the columns in the underlying DataTable (CurrentDataTable). This is controlled by the Fill method used (i.e. by the SQL statement or sproc used to fill the DataTable). The DataTable is not limited to the columns defined as strongly typed properties of the BO...it can have extra columns if needed (it also doesn't have to have all columns needed by the strongly typed properties either, you can leave some out too). If you have a custom property that gets its data from an extra column that you loaded into the DataTable, then you could appear to use that custom property to filter the DataTable.
However, what you seem to desire is a way to limit the data retrieved by the user from the database. In this case you don't actually want to use the BO.Filter. It limits what is shown to the user after all the data has been retrieved (disconnected data model of .NET). So, instead you have to limit the data retrieved within a Fill method.
To limit the data retrieved, you provide Fill methods that do filtering for you, via a SQL statement or Sproc. In the case of filtering on the TotalOrders, you'd need a Fill method that accepted the criterion (and optionally the comparison operator) and build the SQL statement/command. This can get exciting if you have lots of possible filtering fields/options. I use this extensively as my users are all remote, so network latency is a big issue.
If the data retrieved isn't really the issue, then you can use the BO filter options, along with a custom property by using a Fill method that returns the extra columns, then the BO's Filter will work. I.e. your fill SQL might look like this:
Select
CustomerID
,CustomerName
,(Select Count(*)
From Orders
Where o.CustomerID = Customers.CustomerID) As TotalOrders
From Customers
Then, have your custom property use the data in the data table...
return (integer)this.CurrentRow("TotalOrders")
Now, if I'm correct, setting the Filter of the BO to "TotalOrders>100" should work. However, this does not limit the data on the wire. All the data is pulled and it only filters what the user sees. So, if there are 10,000 customers, but only 10 with TotalOrders > 100, this pulls 10,000 from the database and then user can choose to see only 10 of them. |
| | | | StrataFrame User
       
Group: StrataFrame Users Last Login: Yesterday @ 6:32:47 PM Posts: 349, Visits: 1,205 |
| Greg McGuffey (01/28/2008) It really has nothing to do with the custom property, but everything to do with the columns in the underlying DataTableI am starting to see that. Nevertheless, I am still quite confused about the custom property thing. To me, the business object is an ideal place for some of these things. The database is not the best location. You and Trent are suggesting that I need to relocate the business logic back into the database. Here is an example of some custom properties on the Parts business object that I have (declarations/tags/comments removed for brevity): public int OnWorkOrder { get { string mPartindex = this.partindex.ToString(); return (int)ExecuteScalar("spx_GetAmountOnWorkOrder '" + mPartindex + "'"); } }public int OnSalesOrder { get { string mPartindex = this.partindex.ToString(); return (int)ExecuteScalar("spx_GetAmountOnSalesOrder '" + mPartindex + "'"); } }
public int RequiredQty { get { int mReqQty = (this.minstocklevel - this.onhandqty) + (this.OnSalesOrder - this.OnWorkOrder); if (mReqQty < 0) mReqQty = 0; return mReqQty; } }As you can see, the logic becomes rather complex. Easily handled in the business object. The stored procedure that would handle this same stuff would be atrocious...doable, but a near nightmare to construct. I really do not want to put all this back into the DB. If I do, then these custom properties become unneeded. In fact, I cannot see a good use for custom properties, since all of this can be done in the DB.
Bill |
| | | | StrataFrame User
       
Group: StrataFrame Users Last Login: Yesterday @ 6:32:47 PM Posts: 349, Visits: 1,205 |
| | A custom property shows up in the field list when creating a browse dialog. I receive the following error when trying to execute a search on a custom field: ArgumentException An item with the same key has already been added. Source : mscorlib Stack Trace: at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogSearchingEventArgs..ctor(BrowseDialog Browse, WhereStatementCollection WhereStatements) at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.ExecuteSearch() at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.tsiSearch_Click(Object sender, EventArgs e) at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e) at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ToolStrip.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativewindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativewindow.WndProc(Message& m) at System.Windows.Forms.Nativewindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Thought I had something there...I was going to plop a browsedialog on the form and force the user to work through that (with the custom property set to not visible). Not sure what that error means, but I assume it is saying, "Uh uh uh!". That won't work, I guess. |
| | | | StrataFrame User
       
Group: StrataFrame Users Last Login: Today @ 12:50:49 AM Posts: 217, Visits: 1,057 |
| Hi Bill,While our apps are not 'net based I think our general approach could be useful to you: 1) We have a BO for a particualar table. In this exaple the PUN (Packing Unit) table. 2) This BO has number of methods that are used to retrieve data. In the example below it is calling a proc that returns data just for a specific Station Type (which isn't part of the PUN table) and if the PUN is in stock or not and the order in which we want to data to be returned. In our case stp_boPUN is very generic and extracts and sorts data in various ways depending what parameters are passed in ' Populate the BO with all in stock PUNs for a specific station type. Public Sub GetPUNInStock(ByVal StationType As String) Dim ProcParam(2) As System.Data.SqlClient.SqlParameter ProcParam(0) = New System.Data.SqlClient.SqlParameter With ProcParam(0) .ParameterName = "@INSStationType" .DbType = Data.DbType.String .Direction = Data.ParameterDirection.Input .Value = StationType End With ProcParam(1) = New System.Data.SqlClient.SqlParameter With ProcParam(1) .ParameterName = "@InStock" .DbType = Data.DbType.Boolean .Direction = Data.ParameterDirection.Input .Value = 1 End With ProcParam(2) = New System.Data.SqlClient.SqlParameter With ProcParam(2) .ParameterName = "@OrderBy" .DbType = Data.DbType.Int16 .Direction = Data.ParameterDirection.Input .Value = 1 End With Dim cmd As New SqlCommand cmd.CommandType = Data.CommandType.StoredProcedure cmd.CommandText = "stp_boPUN" cmd.Parameters.AddRange(ProcParam) Me.TMSFillUsingCommand(cmd) cmd.Dispose() End Sub 3) Me.TMSFillUsingCommand(cmd) is executed to fill the PUN BO with just the data we want. 4) Me.TMSFillUsingCommand is just a wrapper we have for all our DAL code that does things like error handling / retries etc. The main point is that, in the end, it executes the standard SF fill method using a command string. 5) In our form we would execute Me.boPUN.GetPUNInStock(StationType) and that's it. If the BO was the basis for a grid (we use DevExpress) the grid is automatically refreshed with the new data set. Bottom line is that we use specific stored procs to do the work and only return the data we want. Cheers, Peter |
| | | | |
|