Generate typed business foundation classes
Describes how to generate a typed Business Foundation (BF) class. It also describes code generation and templates to facilitate access to and modification of business foundation data.
Business Foundation (BF) is an Object Relational Mapping (ORM) tool built into Optimizely Commerce Connect that lets you store custom data that does not fit into the data model. You usually need to store custom data, such as data related to customer pricing, gift cards, and authentication SSO tickets.
Here is a summary of BF entities:
- BF entities are not typed, with string names for fields everywhere in the code. This is error-prone. Use string constants to make sure they are defined only once.
- Caching is not built into BF, unlike the catalog, customer, and order subsystems.
- The interface to retrieve BF entities is generic, which causes low code readability.
- BF provides most of what is needed for paging but lacks a returned record count. When paging is set up, you need to know the following:
- what first record is needed on a page
- the number of records to be returned
- the total number of records available to the paging control (so the number of pages can be calculated)
BF lets you input only the first two parameters and does not give you a count of the total number of records matching the query.
The following example shows entities using the existing BF objects:
//Get a list of gift cards the old way
EntityObject[] giftCardEOs1 = BusinessManager.List("GiftCard", new FilterElement[0]);
//or filter the gift card list this way
FilterElement fe1 = new FilterElement("Amount", FilterElementType.Greater, 4.80m);
EntityObject[] giftCardEOs2 = BusinessManager.List("GiftCard", new FilterElement[]{fe1});
//paging...
//this search is the equivelent of :
//"Return all gift cards where the expiration date is after 8/16/2012 and either a) the amount is less than 5 or b) the security code is less than 500"
List<FilterElement> filters = new List<FilterElement>();
filters.Add(new FilterElement("ExpirationDate", FilterElementType.GreaterOrEqual, new DateTime(2012, 8, 16)));
filters.Add(new OrBlockFilterElement(new FilterElement("Amount", FilterElementType.Less, 5), new FilterElement("GiftCardSecurityCode", FilterElementType.Less, 500)));
EntityObject[] giftCardEOs3 = BusinessManager.List("GiftCard", filters.ToArray(), new SortingElement[0], 0, 50);
//no way to get the record count without a separate custom approach...
//now using load and accessing fields
EntityObject eo = BusinessManager.Load("GiftCard", new PrimaryKeyId(new Guid("230D2A87-ADF2-4DC8-96C4-00EB6D97C5FC")));
decimal amount = (decimal)eo.Properties["Amount"].Value;
string securityCode = eo.Properties["GiftCardSecurityCode"].Value.ToString();
//updating is the same but doesn't accept the typed class.
BusinessManager.Update(eo);
//Initializing and creating a new entity object
EntityObject eo2 = BusinessManager.InitializeEntity("GiftCard");
eo2.Properties["ExpirationDate"].Value = DateTime.Now.AddYears(2);
Random RandNum = new Random();
int MyRandomNumber = RandNum.Next(100, 9999);
eo2.Properties["GiftCardSecurityCode"].Value = MyRandomNumber.ToString();
BusinessManager.Create(eo2);
//deleting an entity object
BusinessManager.Delete(eo2);Sample templates and McCodeGen
McCodeGen.exe is a free tool for BF code generation. The following examples show how to create a set of typed business foundation classes, based on example templates and the McCodeGen.exe (provided as a download in the Implement the example code section).
One example of a template is a simple, typed BF class that generates a class file for an existing BF class. It inherits from EntityObject and simply exposes the fields for an EntityObject as typed fields. You can also create templates to create context classes that provide an API to retrieve, update, create, and delete these typed BF objects.
One of the context class templates provides access to the Business Manager methods used to retrieve EntityObject but returns the typed objects instead. The other context class template has this functionality plus caching and full paging support. The latter context class lets you configure the cache timeout.
The typed Business Foundation class template is called EntityObjectSimple.aspx. The non-cached typed BF context class template is EntityObjectAccessTemplateNoCaching.aspx. The cached typed BF context class template is EntityObjectAccessTemplate.aspx.
The following example shows the previous example's code using generated classes:
//get gift card information the new way
GiftCardEntity[] giftCards1 = GiftCardContext.Current.List();
//or filter the gift card list this way.. plus add caching (last parameter in List method
FilterElement fe12 = new FilterElement(GiftCardEntity.FieldAmount, FilterElementType.Greater, 4.80m);
GiftCardEntity[] giftCards2 = GiftCardContext.Current.List(new FilterElement[]{fe12}, true);
//paging...
//this search is the equivelent of :
//"Return all gift cards where the expiration date is after 8/16/2012 and either a) the amount is less than 5 or b) the security code is less than 500"
List<FilterElement> filters2 = new List<FilterElement>();
filters.Add(new FilterElement(GiftCardEntity.FieldExpirationDate, FilterElementType.GreaterOrEqual, new DateTime(2012, 8, 16)));
filters.Add(new OrBlockFilterElement(new FilterElement(GiftCardEntity.FieldAmount, FilterElementType.Less, 5), new FilterElement("GiftCardSecurityCode", FilterElementType.Less, 500)));
GiftCardEntity[] giftCards3 = GiftCardContext.Current.List(filters.ToArray(), new SortingElement[0], 0, 50);
//and the record count can be retrieved
int recordsInLastQuery = GiftCardContext.Current.GetRecordCount(filters.ToArray());
//now using load and accessing fields
GiftCardEntity gc = GiftCardContext.Current.Load(new PrimaryKeyId(new Guid("230D2A87-ADF2-4DC8-96C4-00EB6D97C5FC")));
decimal gcAmount = gc.Amount.Value; //in this case, amount is nullable
string gcSecurityCode = gc.GiftCardSecurityCode;
//updating with typed class
GiftCardContext.Current.Save(gc);
// creating a new typed business foundation object is simpler... plus caching added
GiftCardEntity gc2 = new GiftCardEntity();
gc2.ExpirationDate = DateTime.Now.AddYears(2);
Random RandNum2 = new Random();
int MyRandomNumber2 = RandNum2.Next(100, 9999);
gc2.GiftCardSecurityCode = MyRandomNumber2.ToString();
GiftCardContext.Current.Save(gc2, true);
//deleting an entity object
GiftCardContext.Current.Delete(gc2);Explore the classes created
When you explore the classes created in this example, consider:
- Classes generated by the class template have an
ExtendedPropertiesproperty to provide access to fields that are added to the business foundation entity definition but not defined in the class (for example, because the class was not updated after a field was added). - Classes generated by the cached context class provide overloads to use a member Boolean property value to determine whether to use the cache, or override the member Boolean indicator with your own specific caching indicator. You can set a default value for whether records are cached or retrieved from the cache and override it when needed.
- The cached context class template explicitly defines cache timeout period. You can change the template to your desired timeout or use config settings to set them.
- Both context classes are singletons.
- The record count takes the
FilterElementsto build a dynamic SQL query and returns a count of the number of records matching theList(/Search)conditions.
Implement the example code
- Unzip the download with code and templates.
- Add the following .dlls to the
bindirectory.Mediachase.BusinessFoundation.Data.dllMediachase.BusinessFoundation.Data.XmlSerializers.dllMediachase.BusinessFoundation.ObjectModel.dllMediachase.CodeGen.dllMediachase.CodeGen.VisualStudio.dllMediachase.Ibn.Core.dllMediachase.Ibn.Core.XmlSerializers.dllMediachase.Ibn.Data.dllMediachase.Ibn.Data.Services.dllMediachase.Ibn.Data.XmlSerializers.dllMediachase.Ibn.ObjectModel.dll
- Copy a
.mcgenfile (it does not matter which one) to therootfolder. Rename the.mcgenfile so that it is clear which BF class it is associated with and the class' purpose. - Open the newly-copied version of the .mcgen file in the
rootfolder.
a. Set theconnectionStringelement value to the connection string for the Optimizely Commerce Connect database containing the BF class definition.
b. Set theMetaClasselement value to the name of the BF class you are typing.
c. In the mcgen element, set the template for the class you want to use, such asTemplates\EntityObjectAccessTemplate.aspx; see the descriptions of the templates above.
d. In the params definition, set the namespaceparamvalue to the namespace you would like the class to contain, such asEPiServer.Training.BusinessObjects. - Open a command line to the root folder. Run the following command:
mccodegen -mcgen:: -out:For example:mccodegen -mcgen:GiftCard.mcgen -out:GiftCardAccess.csA new class is created based on the specified template. Use the typed class template to generate the typed BF class. Use one of the context class templates to generate the context class to access the typed BF class. - For each typed class or context class you want to create, iterate through steps 2-5.
Updated 15 days ago
