using System.Collections.Generic; using System.Linq; namespace Quadarax.Foundation.Core.Data.Transaction { /// /// Represents a collection of data transactions that track changes to entity properties. /// Provides functionality to manage, deduplicate, and optimize change records. /// public class DataTransactionCollection : List, IDataTransactionCollection { /// /// Adds a new data transaction to the collection. /// /// The name of the property that was changed. /// The type of transaction (Add/Remove/Change). /// The new value of the property, or null if the property was removed. public void Add(string propertyName, DataTransaction.TransactionTypeEnum transactionType, string? value) { // Implementation goes here } /// /// Deduplicates the collection by removing redundant transactions while preserving /// the effective changes to entity properties. /// /// Deduplication follows these rules: /// 1. If multiple changes exist for the same property, only the most recent one is kept. /// 2. If both Add and Remove transactions exist for the same property, both are removed /// as they cancel each other out. /// 3. Properties are uniquely identified by both name and whether they represent /// reference keys (IsValueKey). /// /// The number of transactions removed during deduplication. public int Deduplicate() { var originalCount = Count; // Group transactions by property name AND whether it's a value key // This ensures we don't mix regular value changes with reference key changes var groupedTransactions = this.GroupBy(x => new { x.PropertyName, x.IsValueKey }) .ToDictionary(g => g.Key, g => g.ToList()); // Clear the existing collection Clear(); foreach (var propertyGroup in groupedTransactions) { string propertyName = propertyGroup.Key.PropertyName; bool isValueKey = propertyGroup.Key.IsValueKey; var transactions = propertyGroup.Value; // If there's only one transaction for this property, just add it if (transactions.Count == 1) { Add(transactions[0]); continue; } // Check for Insert followed by Delete scenario - both can be removed var hasInsert = transactions.Any(t => t.TransactionType == DataTransaction.TransactionTypeEnum.Add); var hasDelete = transactions.Any(t => t.TransactionType == DataTransaction.TransactionTypeEnum.Remove); if (hasInsert && hasDelete) { // Skip this property entirely - the operations cancel each other out continue; } // For other cases, keep only the last transaction for this property Add(transactions.Last()); } // Return the number of items removed return originalCount - Count; } } }