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;
}
}
}