November Happy Hour will be moved to Thursday December 5th.

Extending the properties on the Commerce 'Contact' object with MetaFields

Vote:
 

I can see in the below database that all entries with the `MetaClassId` of 2 are properties that are included in the `Contact` class.

 [dbo].[mcmd_MetaField]

I have two questions:

  1. What repository do I use to access this object programmatically and what is the object called?
  2. Once accessed, how can I use the `MetaFields` functionality to add a new property to the object? More specifically, I want to add 'Gender' as a property as it isn't currently included.
#280231
May 12, 2022 13:12
Vote:
 

Support directed me to the following repo.

#280277
May 13, 2022 8:06
Vote:
 
  1. Gain access to the Contact object:

    CustomerContext.Current.GetContactById(customerId);

  2. You can add new metafields to the contact object via an initialization module or a migration step. I prefer doing it in a migration step. Here's the reference for it: https://docs.developers.optimizely.com/commerce/v14.0.0-commerce-cloud/docs/metafield-class
    FYI it is  best practice to check if the field already exists before attempting to create it.
    The class name for the contact object is "Contact".

#280278
May 13, 2022 8:12
Vote:
 

Using SiteInitializationModule is correct. We created a MetaDataHelper to extend our existing table columns.

var contactMetaClass = MetaDataHelpers.GetOrCreateMetaClass(ContactEntity.ClassName);
public static Mediachase.BusinessFoundation.Data.Meta.Management.MetaClass GetOrCreateMetaClass(string metaClassName, string metaClassFriendlyName = null)
{
	var metaClass = DataContext.Current.MetaModel.MetaClasses
		.Cast<Mediachase.BusinessFoundation.Data.Meta.Management.MetaClass>()
		.FirstOrDefault(mc => mc.Name == metaClassName) ?? CreateMetaClass(metaClassName, metaClassFriendlyName ?? metaClassName);

	return metaClass;
}
private static Mediachase.BusinessFoundation.Data.Meta.Management.MetaClass CreateMetaClass(string metaClassName, string metaClassFriendlyName)
{
	var metaClass = default(Mediachase.BusinessFoundation.Data.Meta.Management.MetaClass);
	using (Mediachase.BusinessFoundation.Data.Meta.Management.MetaClassManagerEditScope scope = DataContext.Current.MetaModel.BeginEdit())
	{
		metaClass = DataContext.Current.MetaModel.CreateMetaClass(metaClassName, metaClassFriendlyName);
		scope.SaveChanges();
	}
	return metaClass;
}

Lastly, You would add the field to the metaObject of Contact as desired - 

var fieldsMetaData = new List<FieldMetaData>()
{
	new FieldMetaData()
	{
		Name = BusinessFoundation.Gender,
		FriendlyName = BusinessFoundation.Gender,
		Type = MetaFieldType.Text,
		StringLength = 30
	}
}

AddFields(contactMetaClass, fieldsMetaData);

private void AddFields(MetaClass metaClass, List<FieldMetaData> fieldsMetaData)
{
	if (metaClass == null || !fieldsMetaData.SafeAny())
	{
		return;
	}
	using (var builder = new MetaFieldBuilder(metaClass))
	{
		foreach (var fieldMetaData in fieldsMetaData)
		{
			MetaDataHelpers.CreateMetaField(builder, metaClass, fieldMetaData);
		}
		builder.SaveChanges();
	}
}
#280524
Edited, May 18, 2022 10:29
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.