---
title: Packages and bundles
slug: commerce-connect-14/docs/bundles-and-packages
docTags: 
createdAt: 2026-07-23T10:25:33.361Z
---

For an introduction to these concepts, see [Packages and bundles](docId\:zAmAvx8RZkwCML0LkTa3J) in the user documentation.

- The `EPiServer.Commerce.Catalog.Linking.BundleEntry` class represents bundle entries.
- The `EPiServer.Commerce.Catalog.Linking.PackageEntry` class represents package entries.
- The `EPiServer.Commerce.Catalog.Linking.IRelationRepository` service administers each.

The `Child` property of the `BundleEntry` or `PackageEntry` contains the `ContentReference` of the entry included in the bundle/package. The class also has a `SortOrder` property for ordering the entries, a `GroupName` property for grouping entries, and a `Quantity` property containing the quantity of the entry in the bundle/package.

`EPiServer.Commerce.Catalog.Linking.EntryRelation` contains the following default values: `DefaultGroupName` and `DefaultQuantity`.

A `BundleEntry` or `PackageEntry` is uniquely defined by the `ContentReference` in its `Child` property together with its `Parent` property (referencing the bundle or package itself). That is, you cannot add the same entry more than once to the same bundle or package.

## Get the entries of a bundle/package

To get bundle/package entries, call the `GetChildren` method of `IRelationRepository` with the `ContentReference` of a bundle/package.

Sample code

```csharp
// Retrieve entries from a bundle 
    public IEnumerable<BundleEntry> ListBundleEntries(ContentReference referenceToBundle)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Relations to bundle entries are of type BundleEntry
        var bundleEntries = relationRepository.GetChildren<BundleEntry>(referenceToBundle);
        return bundleEntries;
      }
    
    // Retrieve entries from a package
    public IEnumerable<PackageEntry> ListPackageEntries(ContentReference referenceToPackage)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Relations to package entries are of type PackageEntry
        var packageEntries = relationRepository.GetChildren<PackageEntry>(referenceToPackage);
        return packageEntries;
      }
```

Or, you can get the bundle/package entry links from bundle/package content via bundle/package content extensions:

Sample code

```csharp
public IEnumerable<ContentReference> ListBundleEntries(BundleContent bundleContent)
      {
        var bundleEntryLinks = bundleContent.GetEntries();
        return bundleEntryLinks;
      }
    
    public IEnumerable<ContentReference> ListPackageEntries(PackageContent packageContent)
      {
        var packageEntryLinks = packageContent.GetEntries();
        return packageEntryLinks;
      }
```

## Get the bundle/package by an entry

To get the packages/bundles, call the `GetParents` method of `IRelationRepository` with the `ContentReference` of a catalog entry.

Sample code

```csharp
public IEnumerable<BundleEntry> GetBundleByEntry(ContentReference entry)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Relations between bundle and bundle entry is BundleEntry
        var bundleRelations = relationRepository.GetParents<BundleEntry>(entry);
    
        return bundleRelations;
      }
    
    public IEnumerable<PackageEntry> GetPackageByEntry(ContentReference entry)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Relations between package and package entry is PackageEntry
        var packageRelations = relationRepository.GetParents<PackageEntry>(entry);
    
        return packageRelations;
      }
```

Or, you can get the bundle/package links from a child item via entry content extensions:

Sample code

```csharp
public IEnumerable<ContentReference> GetParentBundles(EntryContentBase entryContent)
      {
        var bundleLinks = entryContent.GetParentBundles();
        return bundleLinks;
      }
    
    public IEnumerable<ContentReference> GetParentPackages(EntryContentBase entryContent)
      {
        var packageLinks = entryContent.GetParentPackages();
        return packageLinks;
      }
```

Add an entry to a bundle/package

To add `BundleEntry` or `PackageEntry` objects to a bundle or package, use the `UpdateRelations` method or `UpdateRelation` extension method of `IRelationRepository`. The new entry must have a `Child ContentReference`, a `Parent ContentReference`, and you probably want to specify a `Quantity` and `Group`.

Sample code

```csharp
public void AddBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        var newBundleEntry = new BundleEntry
          {
            GroupName = "GroupX",
            Quantity = 1.0m,
            SortOrder = 100,
            Parent = referenceToBundle,
            Child = referenceToProductOrVariation
          };
    
        relationRepository.UpdateRelation(newBundleEntry);
      }
    
    public void AddPackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        var newPackageEntry = new PackageEntry
          {
            GroupName = "GroupX",
            Quantity = 1.0m,
            SortOrder = 100,
            Parent = referenceToPackage,
            Child = referenceToPackageOrVariation
          };
    
        relationRepository.UpdateRelation(newPackageEntry);
      }
```

## Update an entry in a bundle/package

To update `BundleEntry` or `PackageEntry` objects, such as updating the `Quantity`, use the `UpdateRelations` method or the `UpdateRelation` extension method of `IRelationRepository`. You can construct a new object to replace the old one (matched by the `Parent` and `Child` properties). Or, use `GetParents `to get the existing `Relations`, filter out the object you want to update, and pass it to `UpdateRelation` after changing the value.

Sample code

```csharp
public void UpdateBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation, decimal newQuantity)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
        var bundleEntries = relationRepository.GetChildren<BundleEntry>(referenceToBundle);
    
        // Find the matching BundleEntry by comparing the child, ignoring versions since relations are not version specific
        var matchingEntry = bundleEntries.FirstOrDefault(r => r.Child.CompareToIgnoreWorkID(referenceToProductOrVariation));
    
        // Update if there was a matching entry
        if (matchingEntry != null)
          {
            // Set new data
            matchingEntry.Quantity = newQuantity;
    
            relationRepository.UpdateRelation(matchingEntry);
          }
      }
    
    public void UpdatePackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation, decimal newQuantity)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
        var packageEntries = relationRepository.GetChildren<PackageEntry>(referenceToPackage);
    
        // Find the matching PackageEntry by comparing the child, ignoring versions since relations are not version specific
        var matchingEntry = packageEntries.FirstOrDefault(r => r.Child.CompareToIgnoreWorkID(referenceToPackageOrVariation));
    
        // Update if there was a matching entry
        if (matchingEntry != null)
          {
            // Set new data
            matchingEntry.Quantity = newQuantity;
    
            relationRepository.UpdateRelation(matchingEntry);
          }
      }
```

## Remove an entry from a bundle/package

To remove an entry from a bundle/package, call the `RemoveRelations` method or `RemoveRelation` extension method of `IRelationRepository` with a `BundleEntry` or `PackageEntry` object matching an existing bundle/package entry. You can construct a matching object, or use `GetParents` to get the existing `Relations`, to filter out the object you want to remove and pass it to `RemoveRelation`.

Sample code

```csharp
public void RemoveBundleEntry(ContentReference referenceToBundle, ContentReference referenceToProductOrVariation)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Define a relation matching the one to remove, or use
        // GetRelations to find the one you want to remove and pass that to
        // RemoveRelation
        var relationToRemove = new BundleEntry
          {
            Parent = referenceToBundle,
            Child = referenceToProductOrVariation
          };
    
        // Removes matching BundleEntry, or no action if no match exists
        relationRepository.RemoveRelation(relationToRemove);
      }
    
    public void RemovePackageEntry(ContentReference referenceToPackage, ContentReference referenceToPackageOrVariation)
      {
        var relationRepository = ServiceLocator.Current.GetInstance<IRelationRepository>();
    
        // Define a relation matching the one to remove, or use
        // GetRelations to find the one you want to remove and pass that to
        // RemoveRelation
        var relationToRemove = new PackageEntry
          {
            Parent = referenceToPackage,
            Child = referenceToPackageOrVariation
          };
    
        // Removes matching PackageEntry, or no action if no match exists
        relationRepository.RemoveRelation(relationToRemove);
      }
```
