Documentation

Ucommerce includes full API reference documentation and lots of helpful articles to help you build your e-commerce site as effortlessly as possible.

Topics Payment Providers
v7.18

Save Custom Data in the Database

Ucommerce has the ability of storing custom information using the data APIs provided out of the box.

To do this you'll need four things 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 Id, e.g. FreeGiftAwardId for our FreeGiftAward table.

Tables should always start with "Ucommerce_" unless you specify the table name directly in your mapping.

All of the conventions can be overridden your mapping.

Mappings are stored in a separate class usually with the same name of the class it's 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 clases 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:

    
    
    namespace MyApp.Entities
    {
    	/// <summary>
    	/// A custom class which doesn't inherit anything.
    	/// </summary>
    	public class MyClass
    	{
    		/// <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; }
    	}
    }
    
    

We want to store objects of the 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're using BaseClassMap as the super type for our map. This is to let FluentNHibernate know that we're mapping a simple class.

    
    
    namespace MyApp.DataAccess.Maps
    {
    	public class MyClassMap : BaseClassMap<MyClass>
    	{
    		public MyClassMap()
    		{
    			//Table used to store data
    			Table("Custom_MyClass");
    
    			// The primary key
    			Id(x => x.MyClassId);
    
    			// Our simple field, FluentNHibernate knows
    			// how they go together because the field and
    			// column are named the same.
    			Map(x => x.SomeString);
    		}
    	}
    }
    
    

Mapping an Inherited Type

In this case we're 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.

    
    
    namespace MyApp.Entities
    {
    	/// <summary>
    	/// Adds a new order line to the order with the specified
    	/// product on it and a unit price of zero.
    	/// </summary>
    	/// <remarks>
    	/// Will check for existing generated order lines with the
    	/// SKU in question and only add the new order line if one
    	/// does not exist.
    	/// </remarks>
    	public class FreeGiftAward : Award
    	{
    		/// <summary>
    		/// This property is the primary key.
    		///  </summary>   
    		public virtual int FreeGiftAwardId { get; protected set; }
    		
    		/// <summary>
    		/// Identifier of the product family to add. May not be null.
    		/// </summary>
    		public virtual string Sku { get; set; }
    
    		/// <summary>
    		/// Identifier of the product variant to add. Can be null.
    		/// </summary>
    		public virtual string VariantSku { get; set; }
    	}
    }
    
    

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:

    
    
    namespace MyApp.DataAccess.Maps
    {
    	public class FreeGiftAwardMap : SubclassMap<FreeGiftAward>
    	{
    		public FreeGiftAwardMap()
    		{
    			//Table used to store data
    			Table("Ucommerce_FreeGiftAward");
    
    			//The column holding the primary key
    			KeyColumn("FreeGiftAwardId");
    
    			//Identifier of the FreeGiftAward
    			Map(x => x.FreeGiftAwardId).ReadOnly();
    
    			//Data used by the business logic
    			Map(x => x.Sku).Not.Nullable();
    			Map(x => x.VariantSku).Nullable();
    		}
    	}
    }
    
    

The basics of the implementation is that we map the properties FreeGiftAwardId, Sku and VariantSku. Since our class is a derived type of Award there's 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. It will simply be be scanned for registered maps once registered.

Below is the marker class implementing IContainsNHibernateMappingsTag:

    
    
    namespace MyApp.AssemblyTags
    {
    	/// <summary>
    	/// Only purpose of this class is to mark this assembly as an assembly that contains NHibernateMappings
    	/// This is done by registering this type in the dependeny injection container.
    	/// </summary>
    	public class NHibernateMappingsTag : IContainsNHibernateMappingsTag
    	{
    
    	}
    }
    

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:

    
    
    	public void LoadAndSaveCustomData()
    	{
    		var repository = ObjectFactory.Instance.Resolve<IRepository<FreeGiftAward>>();
    		var awards = repository.Select();
    		
    		var award = new FreeGiftAward();
    		award.Sku = "some data";
    		award.VariantSku = "another piece of data";
    
    		repository.Save(award);
    	}
    
    

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 aditional 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 show 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 standard Ucommerce database.