HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Metadata Plus

Describes Metadata Plus (MDP) 2.0, which is the underlying default storage engine for purchase orders and subscriptions in Optimizely Commerce Connect.

MDP lets you extend any system object with a series of meta-fields. It is similar to object-oriented programming. For example, in object-oriented programming, you can create a base Order class, and then a Purchase Order Type object called PurchaseOrder, which inherits its properties and adds specific fields.

The root meta-class is based on a database table called system meta-class. Consider that an abstract meta-class which you must extend to use when associating extended new attributes with a new meta-class. Order becomes a system meta-class, and PurchaseOrder becomes a meta-class that you can extend.

The instance of the meta-class that holds values is called meta-object.

NameDescription
BinaryMSSQL Common Type
BitMSSQL Common Type
CharMSSQL Common Type
DateTimeMSSQL Common Type
DecimalMSSQL Common Type
FloatMSSQL Common Type
ImageMSSQL Common Type
IntMSSQL Common Type
MoneyMSSQL Common Type
NCharMSSQL Common Type
NTextMSSQL Common Type
NVarCharMSSQL Common Type
RealMSSQL Common Type
UniqueIdentifierMSSQL Common Type
SmallDateTimeMSSQL Common Type
SmallIntMSSQL Common Type
SmallMoneyMSSQL Common Type
TextMSSQL Common Type
TimestampMSSQL Common Type
TinyIntMSSQL Common Type
VarBinaryMSSQL Common Type
VarCharMSSQL Common Type
VariantMSSQL Common Type
NumericMSSQL Common Type
SysnameMSSQL Common Type
IntegerMetadata Type
BooleanMetadata Type
DateMetadata Type
EmailMetadata Type
URLMetadata Type
ShortStringMetadata Type
LongStringMetadata Type
LongHtmlStringMetadata Type
DictionarySingleValueMetadata Type
DictionaryMultiValueMetadata Type
EnumSingleValueMetadata Type
EnumMultiValueMetadata Type
StringDictionaryMetadata Type
FileMetadata Type
ImageFileMetadata Type
MetaObjectMetadata Type

Not all properties have a visual designer associated with them, but you can use all of them to extend the meta-class.

The MDP is designed to give the resulting database structure the fastest performance. When a meta-class is created, the container data table and history tables are created with a corresponding set of stored procedures and full text indexes (if full text functionality is enabled). The appropriate indexes are also put.

Meta-fields and Meta-classes

Meta-fields

Meta-fields describe different properties associated with an element inside Optimizely Customized Commerce. You can create a meta-field of any type supported by Metadata Plus.

Meta-classes

Customized Commerce uses meta-classes to describe different types of elements, such as Categories and Products, that are used in the creation and extension of the Customized Commerce solutions developed. Meta-class is a collection of meta-fields. The following types of meta-classes are defined:

  • Mediachase.MetaDataPlus.System. Used for the built-in OrderGroup elements of Customized Commerce.
  • Mediachase.MetaDataPlus.User. Created when a user defines a new meta-class for a OrderGroup. It is always an extension of one the existing System meta-classes.

Use meta-classes and meta-fields

It is important to understand the concepts of a meta-class and meta-field, which form the basis for purchase orders and subscriptions, to fully understand how they work within Optimizely Customized Commerce. For a better understanding, consider an example of creating a new order type WorkOrder which has the following properties:

  • Hours
  • Matrials
  • Bid
  • FinalPrice

To duplicate this product inside your solution, create a WorkOrder meta-class with the OrderGroup meta-class as its parent. In this example, WorkOrder is of type Mediachase.MetaDataPlus.User, and the built-in OrderGroup meta-class is of type Mediachase.MetaDataPlus.System.

Next, assign the properties to your WorkOrderClass by creating a meta-attribute for each Property, then assigning them to your WorkOrderClass. For example, the Hours property could be a meta-attribute of type Integer, and FinalPrice can be a meta-attribute of type money. After you create these meta-attributes, assign them to your WorkOrderClass.

Create meta-fields

Mediachase.MetaDataPlus.Configurator.MetaField.Create(context: OrderContext.MetaDataContext,
        metaNamespace: "Mediachase.Commerce.Orders.User",
        name: "BidPrice",
        friendlyName: "Bid price",
        description: "Bid Price",
        dataType: MetaDataType.Decimal,
        length: 17,
        allowNulls: true,
        multiLanguageValue: false,
        allowSearch: false,
        isEncrypted: false)

Update meta-fields

var metaField = Mediachase.MetaDataPlus.Configurator.MetaField.Load(OrderContext.MetaDataContext, "BidPrice");
    metaField.Description = "Better desciption";
    metaField.OnUpdated();

Delete meta-fields

var metaField = Mediachase.MetaDataPlus.Configurator.MetaField.Load(OrderContext.MetaDataContext, "BidPrice");
    Mediachase.MetaDataPlus.Configurator.MetaField.Delete(OrderContext.MetaDataContext, metaField.Id);

Create meta-classes

var orderGroupClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Load(OrderContext.MetaDataContext, "OrderGroup");
    var metaClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Create(OrderContext.MetaDataContext, "WorkOrder", "Work Order", "WorkOrder", orderGroupClass, false, "Work Order" );

Update meta-classes

var metaClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Load(OrderContext.MetaDataContext, "WorkOrder");
    metaClass.FriendlyName = "Work order change";

Delete meta-classes

var metaClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Load(OrderContext.MetaDataContext, "WorkOrder");
    Mediachase.MetaDataPlus.Configurator.MetaClass.Delete(OrderContext.MetaDataContext, metaClass.Id);

Add meta-felds to meta-classes

var metaClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Load(OrderContext.MetaDataContext, "WorkOrder");
    var metaField = Mediachase.MetaDataPlus.Configurator.MetaField.Load(OrderContext.MetaDataContext, "BidPrice") ?? Mediachase.MetaDataPlus.Configurator.MetaField.Create(
        context: OrderContext.MetaDataContext,
        metaNamespace: metaClass.Namespace,
        name: "BidPrice",
        friendlyName: "Bid Price",
        description: "Bid Price",
        dataType: MetaDataType.Decimal,
        length: 17,
        allowNulls: true,
        multiLanguageValue: false,
        allowSearch: false,
        isEncrypted: false);
    
    if (metaClass.MetaFields.All(x => x.Id != metaField.Id))
    {
        metaClass.AddField(metaField);
    }
    else if (!metaField.DataType.Equals(MetaDataType.Decimal))
    {
        metaClass.DeleteField(metaField.Name);
        Mediachase.MetaDataPlus.Configurator.MetaField.Delete(OrderContext.MetaDataContext, metaField.Id);
        metaField = Mediachase.MetaDataPlus.Configurator.MetaField.Create(context: OrderContext.MetaDataContext,
            metaNamespace: metaClass.Namespace,
            name: "BidPrice",
            friendlyName: "Bid Price",
            description: "Bid Price",
            dataType: MetaDataType.Decimal,
            length: 17,
            allowNulls: true,
            multiLanguageValue: false,
            allowSearch: false,
            isEncrypted: false);
        metaClass.AddField(metaField);
    }

Remove meta-fields from meta-classes

var metaClass = Mediachase.MetaDataPlus.Configurator.MetaClass.Load(OrderContext.MetaDataContext, "WorkOrder");
    metaClass.DeleteField("BidPrice");