New relation APIs in Episerver Commerce 11
Recently, Episerver has changed relation APIs. Now those are easier to understand and use.
The first change you will notice when working with new relations is that now it uses Parent/Child properties instead of Source/Target ones. It makes the code easier to understand. Here is how it looks like for different relations:
- ProductVariation - the parent property has a reference to a product and the child property has a reference to a variation of this product.
- PackageEntry and BundleEntry - the parent property has a reference to a package or a bundle and the child property has a reference to a product which is within the package or the bundle.
- NodeRelation - the parent property has a reference to a category and the child property has a reference to a product or a sub-category which are under the parent category.
In Commerce 11, Episerver had made more internal changes to the relations. One important change is related to URL creation for catalog contents. Previously Episerver used ParentLink on the catalog item to find all parents of it and build URL like http://mysite.com/root/parent1/parent2/product. But now it uses relations instead. Now category/product (node) relation is used to build URLs. But as there might be multiple category/product relations for each item, there is a special relation - the primary relation. Until the Commerce 11.2, there was no easy way to find out which relation is primary. It was created automatically on catalog item creation or moving. While it was a special relation, you could find it with IRelationRepository.GetParents<NodeRelation>(ContentReference link) or IRelationRepository.GetChildren<NodeRelation>(ContentReference link) and delete it with IRelationRepository.RemoveRelation(NodeRelation relation). And there was no way how to get it back.
Episerver has added a new relation type in Commerce 11.2 which solves this issue - NodeEntryRelation. This relation has a property IsPrimary which allows you to distinguish primary relations from other ones. You should not use the old NodeRelation now but use NodeEntryRelation instead. Now you can find relations which are and are not primary and even if you remove the primary relation, you can get it back by creating the new one.
Now you can get children of the parent category like this:
var children = _relationRepository.GetChildren<NodeEntryRelation>(parentLink);
And if you want to remove all related categories except the primary category for the item:
var parents =
_relationRepository
.GetParents<NodeEntryRelation>(childLink)
.Where(x => !x.IsPrimary);
_relationRepository.RemoveRelations(parents);
Another improvement all relation types have is sorting. Now each relation has a SortOrder property. You can use it to order the items as you want. You can set this property from the code, or you can sort products from the UI (category sorting not supported yet), and it will be updated.
Summary
I think that the issue with NodeRelation and primary categories could be omitted if primary node relations would not be listed in GetParents or GetChildren methods. This way it would remain as an internal API. And if the developer would want to change the primary category, he could still use the ParentLink property of an item.
Anyway, Episerver has done a lot of useful improvements in the relation APIs. While there were some issues with it in early Commerce 11 versions, now those are fixed with new NodeEntryRelation.