StrataFrame Forum

Multiple Tables in an object

http://forum.strataframe.net/Topic45.aspx

By Robert Harvey - 11/21/2005

Let's say I have a strongly-typed dataset that contains multiple tables.  And, let's call this dataset 'Orders'.  How can I create an object with Strata-frame?  All of the documentation points to one table per object.  Not that the attachment is a 'real-life' example.  But, I don't want to upload what I use at our company for public consumption.
By StrataFrame Team - 11/21/2005

OK,



I definitely agree that you should never post anything on this forum that is part of your company’s product. And this example definitely says what you need it to say.



There are a few ways you could handle this all are based on the assumption that the sample you gave actually comprises 2 tables within the database (we are talking about a relational database, right?).



1)Create a business object (we’ll call it CompanyBO) and map it to the Company table. Create a business object (we’ll call it StateBO) and map it to the State table. Work with the two separate business objects in code (when you populate the CompanyBO, you can turn around and populate the StateBO etc...)



2)(the better way) Create a complex business object made up of a business object within a business object (result will be similar to the way an Object Relational Mapper would handle it). You could override the State property to return a StateBO object that is automatically filtered based upon the ParentRelationship. When you populate the CompanyBO, it would automatically populate an internal StateBO that would be returned through the State property.



What language are you working with and I could send you a sample project on how I would do it.
By Daniel Essin - 11/21/2005

Perhaps you could post this sample for downlaod. I use C#.



Thanks
By Robert Harvey - 11/21/2005

I have created a similar object using CSLA.  But, it was an icky amount of code to accomplish this.  I started with a base object that inherited System.Data.Dataset.  Then I inherited that object and exposed a dataset property.  A getOrder method to fill it. 

Oh yeah....I use VB. 

By Robert Harvey - 11/21/2005

But, you can post in C#.  Either way works for me.
By StrataFrame Team - 11/21/2005

I'll get it posted ASAP in the morning.
By StrataFrame Team - 11/22/2005

OK, I've uploaded a sample for both C# and VB. Both are identical except where they add the handlers for the events, of course. A little explaination is in order for the samples:



1) All of the necessary code is contained within the "Necessary Code for Complex Business Object" region in the CompanyBO.* file.

2) No extra code was added to the StateBO.

3) You will have to go into the Business Object Mapper and "customize" the State field on the CompanyBO and set it to use "custom code" that will return the readonly property containing the StateBO.

4) I updated the MicroFour StrataFrame AddIns.dll to modify the Business Object Mapper so that it will not create a FieldPropertyDescriptor for a field overriden with custom code. It will be available in the next update. So, if you reproduce this sample before the next update, you will just have to delete the FieldPropertyDescriptor that is created for the State field on the CompanyBO (it won't work and will just assume the field is still a System.String).



---------------------------

Remember, a business object in StrataFrame is just a class, so anything you want to do with it, you can. Just don't modify the designer file outside of the "Component Implementation" region or your changes will be overriden.
By Michael Cobb - 7/12/2007

Hi Ben.  I'm struggling to understand the VB sample. 

You will have to go into the Business Object Mapper and "customize" the State field on the CompanyBO and set it to use "custom code" that will return the readonly property containing the StateBO.

Do I need to create a custom field property for the state in the CompanyBO?  In the Business Object Mapper, what do I need to put in the "custom code" for the State field on the CompanyBO? 

I updated the MicroFour StrataFrame AddIns.dll to modify the Business Object Mapper so that it will not create a FieldPropertyDescriptor for a field overriden with custom code. It will be available in the next update. So, if you reproduce this sample before the next update, you will just have to delete the FieldPropertyDescriptor that is created for the State field on the CompanyBO (it won't work and will just assume the field is still a System.String).

Meaning I would not check the box to create a descriptor?  I apologize for being slow.  Is there a sample project that illustrates the use of the BO Mapper to create custom code?

By StrataFrame Team - 7/13/2007

No, sorry, there aren't any samples that include any of the data for the business object mapper (because we would have to put records into the StrataFrame database to do so...).  So, to explain things a bit better... on the custom code, you would want to put the exact code that would be replace the property that you are customizing.  Meaning that whatever you put in the custom code box will be placed in the partial class as the code for that field property; so, if you wanted to not include a field, then just customize it and leave it completely blank...

As for your second question, yes, you would want to leave the Create Field Descriptor unchecked or the BOMapper will create the FieldPropertyDescriptor for that property.

By Charles R Hankey - 7/13/2007

Trying to follow along here and perhaps someone will take pity on the XML challenged. I see the XSD schema so I can easily visualize the table structures we're talking about. I see these are not tables currently in the SF sample data.



I downloaded the sample and see to BOs, but I of course have nothing to map them to in sql server.



Since Robert passed his data structure as an XSD Schema and Ben had that data structure in the BO in the sample I think I might be missing something everyone who is not VS - XML challenged knows.



Is there a command to create the tables in SQL Server from the XSD schema ? Aside from doubleclicking the schema and seeing it open into a nice data diagram in VS2005 are there other tricks you can do with it in sql server / VS / DDT that one should know about ?



(understanding everything else involved in the complex business object sample will just require my wading out of the newbie phase in SF )



Any guidance appreciated.

Unsure






By StrataFrame Team - 7/16/2007

Is there a command to create the tables in SQL Server from the XSD schema ?

Not that I'm aware of... I wouldn't suspect that it would be in SQL Server Management Studio, but it certainly wouldn't surprise me if there was a 3rd party tool that would do it. 

I downloaded the sample and see to BOs, but I of course have nothing to map them to in sql server.

Hrm... the StrataFrameSample database with sample data should be deployed by the SF install to the same server that the StrataFrame database was installed.  So, unless you skipped that option, you should have some sample data somewhere.

By Charles R Hankey - 7/16/2007

Smile uh, no I have the SF sample database installed.

My point was the data schema Robert send was for two tables that aren't part of the sample data

And I was wondering if before creating the sample you had somehow magically imported from the schema into a DB so you could map with the BO mapper.

I think I was having a bad expressing myself day BigGrin

( but it did get me Googling and it turns out there is indeed a way to create XSD Schemas from SQL 2005 with t_sql and then the there a way of creating data structures in SQL from schemas, but the format Robert used wasn't the one, so I guess that wasn't the intention )

Just trying to catch up on the huge gaps in my basic knowledge of VS/VB tricks w00t

By StrataFrame Team - 7/16/2007

Ah, I gotcha... the XSD that Robert posted is not part of the StrataFrameSample database... it was something else that he was working on (or maybe he modified his sample database, I dunno).  So, it's starting to make sense why you thought that the XSD he posted was part of the SF sample. 

I'm glad you found a few tools to convert the XSDs and so forth.  But just remember, the only 2 sources of structures for the BOMapper are the DDT and the database itself on the server.

By Michael Cobb - 7/18/2007

Charles:  The way I did this was to add a State table to the SF Sample database.  The table consists of StateName and StateCode columns.  StateName has the long names and StateCode has the abbreviations.  Then I went into the VB.NET CRMApplication sample.  I added a BO called StateBO to that project and used the BusinessObjectMapper to create the partial class for it. 

I added the following custom code to the StateBO for a parameterless data retrieval method:

''' <summary>

''' Fills the business object with all records order by primary key

''' </summary>

''' <remarks></remarks>

Public Sub FillAllStateTable()

'-- Establish local

Dim loCommand As New SqlCommand()

'-- Create the command

loCommand.CommandText = "SELECT * FROM State ORDER BY StateCode"

'-- Execute the command

Me.FillDataTable(loCommand)

End Sub

#End Region

Then I modified the custom code for the CustomersBO by adding the following lines of code only:

Private WithEvents _State As New StateBO()

''' <summary>

''' This method handles the Navigated event of the Customers business object to allow

''' you to set the filter on the State business object.

'''

''' You can filter the StateBO to only show records that match the current record

''' within the CustomersBO.

''' </summary>

''' <param name="e"></param>

Private Sub CustomersBO_Navigated(ByVal e As MicroFour.StrataFrame.Business.NavigatedEventArgs) Handles Me.Navigated

'-- Set the filter on the internal StateBO

' (Only necessary if the CompanyBO will contain more than one record)

Me._State.Filter = "StateCode = '" & CType(Me.CurrentRow("cust_State"), String) & "'"

End Sub

Next I did a BuildAll so that the Company and State Business Objects were recompiled.

To test it, I moved the State Textbox (Textbox9) to the bottom of the form (you could just as easily remove it) and replaced it with a StrataFrame ComboBox on which I set the following properties: BusinessObject=Customers, BindingField = cust_State, DropDownStyle=DropDownList, PopulationType=BusinessObject, PopulationDataSourceSettings=StateBO.FillAllStateTable().  The PopulationDataSourceSettings property gets built by clicking the ellipsis on the property.  Inside there I put {0} under Display Member and Drop-Down Display, StateName under ValueMember and added StateCode to DisplayMember.

When you run the form the combo box will display the state code for the current record as you browse.  If you edit/add a record the combo box displays a list of all possible state codes.  If you change a value and save it, the Customers table will save the state name associated with the state code.

That should get you started if you're still looking at this.

By Michael Cobb - 7/18/2007

Ben,

In the following declaration statement what is the naming convention calling for the variable name to begin with an underline?  Is this typically used for property variables?

Private WithEvents _State As New StateBO()

By Charles R Hankey - 7/18/2007

Thanks Ben - I knew it wasn't part of the Strataframe Sample Data but it was referenced in the zip you posted so I thought you might have used his XSD to add the tables to the sample data in some way everyone but me knew about "Smile
By Charles R Hankey - 7/18/2007

Thanks a lot for this Robert. I'll file it away for when my SF level rises BigGrin
By StrataFrame Team - 7/19/2007

The underscore is just a convention that we use internally.  It's not a .NET naming convention.  However, with VB, when you create a "Public WithEvents MyField As SomeType" field on your class, VS behind the scenes creates a field named the same as your field, but with an underscore (_MyField) and instead of creating a public field, it wraps the implicit private (_MyField) with a public property. 

Other than that, I don't know of any convention that says that your private fields (or any other member fields) need to start with an _.  We just do because we like the convention.  I've looked through the .NET framework using Reflector a few times, and in most of their stuff, they either start their private fields with an _ and camel case them or just camel case them (_myField or myField).  It's entirely up to you.

I can't find the MSDN page that lists the .NET naming conventions, but this guy has most of them listed.  Look down at the one that says "Class-Level Private and Protected Variables"

http://www.irritatedvowel.com/Programming/Standards.aspx

By Michael Cobb - 7/19/2007

Thanks Ben.  I hadn't seen the underscore naming convention except for in the StrataFrame code but I like it and think I will use it as well.
By choyt - 8/22/2007

Hi Folks

I have this working with one caveat.

I have a "Users" table that hold basic inforamtion such as First and Last name but am using forms authentication and want to take full advantage of that so am using the aspnet_ tables as well. To do this, I am joining together my Users table with aspnet_Users and aspnet_Membership. There is no data of use to me in the aspnet_Users table but there is quite a bit of useful info in the membership table.

To do this the way that has been described, I am customizing the UserName field in my user table (the FK to the UserName field in aspnet_Users) and replacing it with a BO that I mapped against aspnet_membership. I would much rather keep my user name field intact but there is no way in the object mapper to create a field. You can only use (override) fields that are aleady part of the underlying database table.

I can see these work arounds

  1. Create a "fake" field in the database to fool the mapper into believing there is an extra field.
  2. Manually modify the designer.vb file each time I do a build (kind of pain but not out of the question)
  3. Overwriting my UserName field.

Is there something simple and basic I'm missing or is my understanding correct?

Thanks! BigGrin

By choyt - 8/22/2007

Ok...I put the property in "my part" of the partial class and this seems to have fixed the problem!
By StrataFrame Team - 8/22/2007

If you want to override a field property that maps to a field in the database, then you will need to use the Custom Code option within the BOMapper and supply the code that you want it to spit out when it creates the partial class.

If you want to create a second property (instead of replacing the property itself), you'll want to create a new property in the main code file so that it does not get overwritten when the partial class is re-created again.  The easiest way to do this is to copy one of the fields from the designer file, paste it into the main code file (attributes and all) and modify it the way you want it.  Then, just override the GetCustomBindablePropertyDescriptors() method and return the property descriptor for that property.  (You should be able to search either the help or the forum for "GetCustomBindablePropertyDescriptors" because it might show you some more information and show you what happens when you don't provide a descriptor BigGrin).