Save Custom Data in the Database
Ucommerce has the ability to store custom information using the data APIs provided out of the box.
To do this you will need four things:
- A class to work with, in .NET
- A table to store your data in the database
- A map to let Ucommerce know how to store the data
- A mapping tag to let Ucommerce know that a particular DLLs contains maps
Fluent NHibernate Mappings
To let Ucommerce know how classes and tables go together we use a map created with Fluent NHibernate.
FluentNHibernate uses conventions to map, which require database fields to have certain names, e.g. the primary key of the table should always be
Tables should always start with "Ucommerce_" unless you specify the table name directly in your mapping.
All of the conventions can be overridden by your mapping.
Mappings are stored in a separate class usually with the same name as the class it is mapping, suffixed with "Map". So in our case, it would be FreeGiftAwardMap
.
You can map both simple types, which do not inherit from any super classes and inherited types.
Mapping a Simple Type
For this example we'll use a very simple class called MyClass
with a primary key and a single string field:
/// <summary> /// A custom class which doesn't inherit anything. /// </summary> public class MyClass : IEntity { /// <summary> /// This property is the primary key. /// </summary> /// <remarks> /// Notice the convention used here. The field uses the same /// name as the class with Id suffixed. /// </remarks> public virtual int MyClassId { get; protected set; } /// <summary> /// A field on the class. /// </summary> public virtual string SomeString { get; set; } public int Id { get; } }
We want to store objects of this type in the following table:
CREATE TABLE Custom_MyClass ( MyClassId int primary key, SomeString nvarchar(max) null )
And finally, we need to tie together the class and the table with our map. Notice that we are using BaseClassMap
as the super type for our map. This is to let FluentNHibernate know that we are mapping a simple class.
public class CustomerMap : Ucommerce.EntitiesV2.Maps.CustomerMap { public CustomerMap() { DiscriminateSubClassesOnColumn("Type", (byte)0).Not.Nullable(); } }
Mapping an Inherited Type
In this case, we are dealing with a new class derived from Award
called FreeGiftAward
. Award
is a standard Ucommerce class, but it could potentially be any class already mapped, either your own or a standard Ucommerce class.
public class MyCustomCustomerMap : SubclassMap<MyCustomCustomer> { public MyCustomCustomerMap() { DiscriminatorValue(1); Map(x => x.ExternalIdentifier); } }
Above is the class with the properties we need to map:
- FreeGiftAwardId
- Sku
- VariantSku
So for this purpose, we need a FreeGiftAwardMap table in the database:
CREATE TABLE Ucommerce_FreeGiftAward ( FreeGiftAwardId int primary key, Sku nvarchar(max) not null, VariantSku nvarchar(max) )
And finally the map, which ties together the table and the class:
public class MyCustomCustomerMapTablePerClass : SubclassMap<MyCustomCustomer> { public MyCustomCustomerMapTablePerClass() { Table("Ucommerce_MyCustomCustomer"); KeyColumn("MyCustomCustomerId"); Map(x => x.ExternalIdentifier); } }
The basic idea of the implementation is that we map the properties FreeGiftAwardId, Sku, and VariantSku. Since our class is a derived type of Award there is no need to specify the primary key as the base class Award
is already dealing with that.
Create Mapping Assembly Tag
With our mappings done it's time to let Ucommerce know about them: The assembly tag will serve as a marker for Ucommerce to know where to locate mappings.
To do so we must implement the interface IContainsNHibernateMappingsTag
, which identifies the assembly as containing mappings.
Below is the marker class implementing IContainsNHibernateMappingsTag
:
var myCustomer = new MyCustomCustomer(); myCustomer.FirstName = "This"; myCustomer.LastName = "Rocks"; myCustomer.EmailAddress = "[email protected]"; myCustomer.ExternalIdentifier = "Mr. Rocks"; myCustomer.Save();
Once the assembly tag is in place Ucommerce will automatically pick up new maps you create so this process is only required once per assembly you want to create maps in; usually once per project.
Please note that it is important that the assembly tag resides the same assembly as your mappings. Otherwise, the mappings will not be picked up.
Register Assembly Tag
All there is left to do is register the new assembly tag as a component so Ucommerce knows where to look for your new maps. To do this we add a new configuration file to Ucommerce/Apps/MyApp
called Mappings.config with the following:
<configuration> <components> <component id="MyAppMappings" service="Ucommerce.EntitiesV2.IContainsNHibernateMappingsTag, Ucommerce" type="MyApp.AssemblyTags.NHibernateMappingsTag, MyApp" /> </components> </configuration>
Please refer to Register a Component if you're interested in more details about components.
Use Your Custom Data
Once your new table, class, and map are in place you can use the LINQ APIs of Ucommerce to work with your data:
var repository = ObjectFactory.Instance.Resolve<IRepository<MyCustomCustomer>>(); MyCustomCustomer customer = repository.SingleOrDefault(x => x.ExternalIdentifier == "Mr. Rocks");
The code above is the same for both simple types and inherited types.
Extending default mappings in Ucommerce
You may find yourself in a situation where you want to extend the default objects in Ucommerce with additional data. It could be as simple as a "CatName" field on the customer object, or even complex objects related to the standard PurchaseOrder object. Anything only limited to the boundaries of what is possible in SQL server :-) To achieve this please read How to extend ucommerce entities
Summary
You have seen how you can plug your own data into Ucommerce and leverage the data access APIs of the platform for yourself.
Additional benefits are that your data will also be able to take advantage of the caching systems available to Ucommerce for both objects and queries as well as the query mechanisms as shown above.
The mapping layers support rich mappings like associations between object so you can also create more advanced data structures like an Order-Customer relationship as well as many-to-many relations between your own data and even with the standard Ucommerce database.