---
title: Metadata Plus
slug: commerce-connect-15/docs/metadata-plus
docTags: 
createdAt: 2026-07-30T20:34:41.000Z
---

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

```csharp
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

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

### Delete meta-fields

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

### Create meta-classes

```csharp
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

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

### Delete meta-classes

```csharp
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

```csharp
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

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