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

Catalog DTO and object models

Describes how to work with caching and catalog entry DTOs (Data Transfer Objects) in Optimizely Commerce Connect.

Catalog entry DTOs and caching

DTOs are simple objects that carry data between processes. Catalog entry DTOs transfer data between an application and the database.

📘

New in Commerce Connect 14

Catalog entry DTOs are cached based on CatalogOptions.

Example:

"EPiServer" : {
      "Commerce" : {
        "CatalogOptions" : {
          "Cache" : {
            "UseCache"                      : true,
            "ContentVersionCacheExpiration" : "00:15:00",
            "CollectionCacheExpiration"     : "00:15:00",
            "EntryCacheExpiration"          : "00:15:00",
            "NodeCacheExpiration"           : "00:15:00"
          }
        }
      }
    }

📘

Versions 10-13

Catalog entry DTOs are cached based on settings inecf.catalog.config.

Example:

<?xml version="1.0"?>
    <Catalog autoConfigure="true">
    <Connection connectionStringName="EcfSqlConnection" />
    <Cache enabled="true" 
           collectionTimeout="0:1:0" 
           entryTimeout="0:1:0" 
           nodeTimeout="0:1:0" 
           schemaTimeout="0:2:0" />

During development, it can be beneficial to disable caching. When deploying your ecommerce site, enable catalog caching and use cache timeouts appropriate for your requirements and environment.

CatalogEntry DTOs are cached based on the response group(s) used to retrieve them. Types of CatalogEntry response groups:

  • Request
  • CatalogEntryInfo
  • CatalogEntryFull
  • Associations
  • Children
  • Assets
  • Nodes
  • Variants
  • Inventory
  • RecursiveAssociations

Catalog entry objects vs. catalog entry DTOs

Entry objects are used to further abstract catalog entry DTOs.

namespace Mediachase.Commerce.Catalog.Objects
    {
        /// <summary>
        /// The Entry parameter serves as a container element that is a child of the Entries element, and
        /// represents the Catalog Entry element, which can be Product, Variant, Bundle or any other type of product.
        /// </summary>
        [Serializable]
        public class Entry
        {
        }
    }

Entry objects are not cached, but the underlying DTOs from which they are constructed are cached.

Import using API

Example: Using the Catalog API data transfer objects (DTOs) to create a catalog entry. The CatalogContext is the main entry point to the Catalog system.

private void SampleEntryAdd()
    {
      int catalogId = 2;
     
      // Get a CatalogDto object.
      CatalogDto catalogDto = CatalogContext.Current.GetCatalogDto(catalogId, new CatalogResponseGroup(CatalogResponseGroup.ResponseGroup.CatalogInfo));
     
      if (catalogDto.Catalog.Count > 0)
      {
        // Get a CatalogEntryDto object.
        CatalogEntryDto entry = CatalogContext.Current.GetCatalogEntryDto("PRODUCT_CODE",
          new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo));
     
        if (entry.CatalogEntry.Count == 0)
        {
          // Get a new entry row for your catalog entry.
          CatalogEntryDto.CatalogEntryRow newEntryRow = entry.CatalogEntry.NewCatalogEntryRow();
     
          // Set entry properties.
          newEntryRow.ApplicationId = AppContext.Current.ApplicationId;
          newEntryRow.CatalogId = catalogDto.Catalog[0].CatalogId;
          newEntryRow.ClassTypeId = "Variation";
          newEntryRow.Code = "PRODUCT_CODE";
          newEntryRow.EndDate = DateTime.Now.AddYears(2).ToUniversalTime();
          newEntryRow.IsActive = true;
          newEntryRow.MetaClassId = 32;
          newEntryRow.Name = "PRODUCT_NAME";
          newEntryRow.StartDate = DateTime.UtcNow;
          newEntryRow.TemplateName = "DigitalCameras"; // system-defined template of type 'entry'
          newEntryRow.SetSerializedDataNull();
          if (newEntryRow.RowState == DataRowState.Detached)
            entry.CatalogEntry.AddCatalogEntryRow(newEntryRow);
     
          // Set variation properties.
          CatalogEntryDto.VariationRow newVariationRow = entry.Variation.NewVariationRow();
          newVariationRow.ListPrice = Convert.ToDecimal(1000.00);
          newVariationRow.MaxQuantity = 50;
          newVariationRow.SetMerchantIdNull();
          newVariationRow.MinQuantity = 5;
          newVariationRow.PackageId = 0;
          newVariationRow.TaxCategoryId = 0;
          newVariationRow.TrackInventory = true;
          newVariationRow.WarehouseId = 0;
          newVariationRow.Weight = Convert.ToDouble(4);
          newVariationRow.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
          if (newVariationRow.RowState == DataRowState.Detached)
            entry.Variation.AddVariationRow(newVariationRow);
     
          // Set inventory properties.
          CatalogEntryDto.InventoryRow newInventoryRow = entry.Inventory.NewInventoryRow();
          newInventoryRow.AllowBackorder = false;
          newInventoryRow.AllowPreorder = false;
          newInventoryRow.ApplicationId = AppContext.Current.ApplicationId;
          newInventoryRow.BackorderAvailabilityDate = DateTime.UtcNow;
          newInventoryRow.BackorderQuantity = 0;
          newInventoryRow.InStockQuantity = Convert.ToDecimal(75);
          newInventoryRow.InventoryStatus = 1;
          newInventoryRow.PreorderAvailabilityDate = DateTime.UtcNow;
          newInventoryRow.PreorderQuantity = 0;
          newInventoryRow.ReorderMinQuantity = 15;
          newInventoryRow.ReservedQuantity = 10;
          newInventoryRow.SkuId = "mark_test7";
          if (newInventoryRow.RowState == DataRowState.Detached)
            entry.Inventory.AddInventoryRow(newInventoryRow);
     
          // Set seo properties.
          CatalogEntryDto.CatalogItemSeoRow newSeoRow = entry.CatalogItemSeo.NewCatalogItemSeoRow();
          newSeoRow.ApplicationId = AppContext.Current.ApplicationId;
          newSeoRow.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
          newSeoRow.CatalogNodeId = 62;
          newSeoRow.Description = "DESCRIPTION";
          newSeoRow.LanguageCode = "en-us";
          newSeoRow.Uri = "SEO-FRIENDLY-URL.aspx";
          if (newSeoRow.RowState == DataRowState.Detached)
            entry.CatalogItemSeo.AddCatalogItemSeoRow(newSeoRow);
     
          // Save the entry.
          CatalogContext.Current.SaveCatalogEntry(entry);
     
          // Save the metadata attributes associated with the catalog entry.
          MetaDataContext metaContext = new MetaDataContext();
          MetaClass metaClass = MetaClass.Load(metaContext, "Publications");
          MetaObject metaObj = MetaObject.NewObject(metaContext, entry.CatalogEntry[0].CatalogEntryId, metaClass.Id, "name");
          MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Title", new object[] { "New Book Title" });
          MetaHelper.SetMetaFieldValue(metaContext, metaObj, "ID", new object[] { "New Id" });
          MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Description", new object[] { "New Description" });
          MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Theme", new object[] { "New Book Title" });
          MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Highlight", new object[] { false });
          metaObj.AcceptChanges(metaContext);
     
          // Set the entry node relation.
          CatalogRelationDto relation = new CatalogRelationDto();
          CatalogRelationDto.NodeEntryRelationRow nodeRelation = relation.NodeEntryRelation.NewNodeEntryRelationRow();
          nodeRelation.CatalogId = 2;
          nodeRelation.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
          nodeRelation.CatalogNodeId = 62;
          nodeRelation.SortOrder = 0;
          if (nodeRelation.RowState == DataRowState.Detached)
            relation.NodeEntryRelation.AddNodeEntryRelationRow(nodeRelation);
     
          // Save the relation.
          CatalogContext.Current.SaveCatalogRelationDto(relation);
        }
      }
    }

Importing multiple language metadata

Example: Creating metadata in multiple languages for a catalog using the MetaHelper.SetMetaFieldValue method.

MetaDataContext MDContext = CatalogContext.MetaDataContext;
    
      MDContext.UseCurrentUICulture = false;
      //string 
      foreach (string language in Languages)
        {
          MDContext.Language = language;
          MetaHelper.SetMetaFieldValue(metaobj)...
          metaObj.AcceptChanges(MDContext);
        }
      MDContext.UseCurrentUICulture = true;