1770725605
2026-02-09 15:00:00
Optimizely CMS では、単純なタイプと複雑なタイプの両方のリストを簡単に保存できます。これは管理が簡単で、エディター インターフェイスに適切に表示され、効率的に保存およびロードされます。
これは、Optimizely World の CMS とコマースの両方でサポートされ、文書化されています。
ただし、公開されているコード サンプルにはパフォーマンスの問題があります。 PropertyList は、その方法を指定しない限り、等価比較を実行しません。
例
現実世界の例を考えてみましょう。
Commerce Connect サイトでは、各製品またはバリエーションのページに製品仕様のリストが保存される場合があります。これらは通常、可変数のキーと値の項目です。したがって、それらをカスタム プロパティ リストとして保存することもできます。
この Commerce Connect サイトは、おそらく外部 PIM または MDM システムからのカタログ データも同期します。
非常にシンプルにするために、関連するすべてのカタログ アイテムを Commerce カタログからプリロードします。入荷する製品またはバリエーションごとに、プリロードされたアイテムから同じアイテムを検索します。次に、受信した値をカタログ プロパティに割り当てます。
以下は、そのようなインポート作業のごく一部を抜粋したものです。
var variationClone = variationContent.CreateWritableClone();
variationClone.Color = colorFromPim;
variationClone.Specifications = specificationsFromPim
.Select(x => new SpecificationItem { Key = x.Key, Value = x.Value })
.ToList();
if (variationClone.IsModified)
{
_contentRepository.Publish(variationContent);
}
このサンプルのバリエーションはいつ保存され、公開されますか?
いつも。なぜなら、variationClone.IsModified は常に true になるからです。
これは、カスタム プロパティ リストのデフォルトの実装では、デフォルトの等価比較子が使用されるためです。そして、これは 2 つの変数が等しいかどうか (同じメモリ位置を指す場合など) のみを考慮します。たとえ内容が同じに見えたとしても。
その結果、ジョブが実行されるたびに、実質的な違いのない不要な新しいコンテンツ バージョンが作成されます。
解決
簡単な解決策は、カスタム リスト プロパティごとにカスタム比較子を作成することです。
この例では、プロパティ リストにこの単純な SpecificItem レコードが格納されています。
public record SpecificationItem
{
public string Key { get; set; }
public string Value { get; set; }
}
これは、対応するプロパティタイプの実装です。 ItemComparer プロパティをオーバーライドする方法に注目してください。
[PropertyDefinitionTypePlugIn]
public class PropertySpecificationList : PropertyList
{
// Use our own item comparer implementation, which specifically check whether the property values are equal.
protected override IEqualityComparerItemComparer => SpecificationItemComparer.Default;
}
そして最後に、ここで魔法が起こります。
public class SpecificationItemComparer : IEqualityComparer
{
// Initialize a static field for easy reuse.
public static readonly SpecificationItemComparer Default = new();// Depending on your needs use string.Equals with explicit StringComparison value, instead of "==".
public bool Equals(SpecificationItem x, SpecificationItem y) =>
ReferenceEquals(x, y) || (x is not null && y is not null && x.Key == y.Key && x.Value == y.Value);public int GetHashCode(SpecificationItem obj) =>
HashCode.Combine(obj.Key, obj.Value);
}
このソリューションは、Optimizely CMS と Commerce Connect で同様に機能します。
#PropertyList #に複合型を格納する場合は注意してください