DataTransactionCollection.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Quadarax.Foundation.Core.Data.Transaction
  5. {
  6. /// <summary>
  7. /// Represents a collection of data transactions that track changes to entity properties.
  8. /// Provides functionality to manage, deduplicate, and optimize change records.
  9. /// </summary>
  10. public class DataTransactionCollection : List<DataTransaction>, IDataTransactionCollection
  11. {
  12. /// <summary>
  13. /// Adds a new data transaction to the collection.
  14. /// </summary>
  15. /// <param name="propertyName">The name of the property that was changed.</param>
  16. /// <param name="transactionType">The type of transaction (Add/Remove/Change).</param>
  17. /// <param name="value">The new value of the property, or null if the property was removed.</param>
  18. public void Add(string propertyName, DataTransaction.TransactionTypeEnum transactionType, string? value)
  19. {
  20. // Implementation goes here
  21. }
  22. /// <summary>
  23. /// Deduplicates the collection by removing redundant transactions while preserving
  24. /// the effective changes to entity properties.
  25. ///
  26. /// Deduplication follows these rules:
  27. /// 1. If multiple changes exist for the same property, only the most recent one is kept.
  28. /// 2. If both Add and Remove transactions exist for the same property, both are removed
  29. /// as they cancel each other out.
  30. /// 3. Properties are uniquely identified by both name and whether they represent
  31. /// reference keys (IsValueKey).
  32. /// </summary>
  33. /// <returns>The number of transactions removed during deduplication.</returns>
  34. public int Deduplicate()
  35. {
  36. var originalCount = Count;
  37. // Group transactions by property name AND whether it's a value key
  38. // This ensures we don't mix regular value changes with reference key changes
  39. var groupedTransactions = this.GroupBy(x => new { x.PropertyName, x.IsValueKey })
  40. .ToDictionary(g => g.Key, g => g.ToList());
  41. // Clear the existing collection
  42. Clear();
  43. foreach (var propertyGroup in groupedTransactions)
  44. {
  45. string propertyName = propertyGroup.Key.PropertyName;
  46. bool isValueKey = propertyGroup.Key.IsValueKey;
  47. var transactions = propertyGroup.Value;
  48. // If there's only one transaction for this property, just add it
  49. if (transactions.Count == 1)
  50. {
  51. Add(transactions[0]);
  52. continue;
  53. }
  54. // Check for Insert followed by Delete scenario - both can be removed
  55. var hasInsert = transactions.Any(t => t.TransactionType == DataTransaction.TransactionTypeEnum.Add);
  56. var hasDelete = transactions.Any(t => t.TransactionType == DataTransaction.TransactionTypeEnum.Remove);
  57. if (hasInsert && hasDelete)
  58. {
  59. // Skip this property entirely - the operations cancel each other out
  60. continue;
  61. }
  62. // For other cases, keep only the last transaction for this property
  63. Add(transactions.Last());
  64. }
  65. // Return the number of items removed
  66. return originalCount - Count;
  67. }
  68. }
  69. }