Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev 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.

Metadata Plus (MDP) lets you extend any system object with a series of meta-fields. The model is similar to object-oriented programming: you can create a base Order class, then create a Purchase Order Type object called PurchaseOrder that inherits the base class properties and adds specific fields.

The root meta-class is based on a database table called system meta-class. Treat this root as an abstract meta-class — extend it whenever you need to associate 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 a meta-class that holds values is called a meta-object.

Metadata Plus supports the following data types when you define meta-fields.

MSSQL common types

These types map directly to SQL Server column types:

  • Binary
  • Bit
  • Char
  • DateTime
  • Decimal
  • Float
  • Image
  • Int
  • Money
  • NChar
  • NText
  • NVarChar
  • Numeric
  • Real
  • SmallDateTime
  • SmallInt
  • SmallMoney
  • Sysname
  • Text
  • Timestamp
  • TinyInt
  • UniqueIdentifier
  • VarBinary
  • VarChar
  • Variant

Metadata Plus types

These types are defined by Metadata Plus and provide higher-level semantics:

  • Boolean
  • Date
  • DictionaryMultiValue
  • DictionarySingleValue
  • Email
  • EnumMultiValue
  • EnumSingleValue
  • File
  • ImageFile
  • Integer
  • LongHtmlString
  • LongString
  • MetaObject
  • ShortString
  • StringDictionary
  • URL

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

MDP is designed for fast database performance. When a meta-class is created, the container data table and history tables are created together with a set of stored procedures and full-text indexes (if full-text functionality is enabled). MDP also adds the appropriate indexes.

Meta-fields and meta-classes

Meta-fields

Meta-fields describe properties associated with an element in Optimizely Commerce Connect. Create a meta-field of any type supported by Metadata Plus.

Meta-classes

Commerce Connect uses meta-classes to describe types of elements, such as Categories and Products, used when you create and extend Commerce Connect solutions. A meta-class is a collection of meta-fields. Commerce Connect defines the following types of meta-classes:

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

Use meta-classes and meta-fields

Meta-classes and meta-fields form the basis for purchase orders and subscriptions in Optimizely Commerce Connect. As an example, consider a new order type WorkOrder with the following properties:

  • Hours
  • Materials
  • Bid
  • FinalPrice

To replicate this order type in 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, create a meta-attribute for each property and assign it to your WorkOrderClass. For example, the Hours property could be a meta-attribute of type Integer, and FinalPrice could be a meta-attribute of type Money.

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 description";
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-fields 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");