Tracking lists
public record Album(int Id, string Title);
List<Album> existingAlbums = cnn.Query<List<Album>>("SELECT AlbumId AS Id, Title FROM albums ORDER BY AlbumId");
static readonly QueryCommand DeleteAlbum = new("DELETE FROM albums WHERE AlbumId = @Id");
Structural tracking with a concrete type
TrackingList<Album> albums = new(existingAlbums);
albums.Add(new Album(0, "New album"));
albums.RemoveAt(0);
Console.WriteLine(albums.AddedCount);
Console.WriteLine(albums.RemovedCount);
TrackingList<T> tracks active membership and structural changes without requiring editable items.
Structural and member tracking together
TrackingList<IRuntimeTrackingItem<Album>> albums = existingAlbums.ToTrackingList();
albums[0].Set(nameof(Album.Title), "Kind of Blue");
Member changes belong to the items. Structural changes belong to the list.
bool structural = albums.HasChanges;
bool memberEdit = albums[0].HasChanges();
AddNew
IRuntimeTrackingItem<Album> item = albums.AddNew();
item.Set(nameof(Album.Title), "New album");
Console.WriteLine(albums.IsAddedAt(albums.Count - 1));
if (albums.CanAddNew)
albums.AddNew();
An already created item can also be inserted.
albums.Add(edit);
albums.Insert(0, edit);
Remove
IRuntimeTrackingItem<Album> removed = albums[0];
albums.RemoveAt(0);
Console.WriteLine(albums.RemovedCount);
An accepted removed item remains in Removed until deletion is confirmed. Removing an item that is still a new addition cancels that addition instead.
Restore
IRuntimeTrackingItem<Album> removed = albums.Removed[0];
albums.Restore(removed);
albums.RestoreAt(0, 2);
Move
albums.Move(0, 3);
Moving changes active order without creating an addition or removal.
Replace
albums[2] = replacement;
The configured comparer determines whether the replacement represents the same item.
TrackingList<AlbumRow> rows = new(existingRows, comparer: EqualityComparer<AlbumRow>.Default);
Enumerate structural changes
foreach (IRuntimeTrackingItem<Album> item in albums.Added)
Console.WriteLine(item.Get<string>(nameof(Album.Title)));
foreach (IRuntimeTrackingItem<Album> item in albums.Removed)
Console.WriteLine(item.Get<int>(nameof(Album.Id)));
Confirm one active operation
bool confirmed = albums.ConfirmAt(0);
The specific operations are also exposed.
albums.ConfirmAddedAt(0);
albums.ConfirmEditAt(1);
Confirm a deletion
IRuntimeTrackingItem<Album> removed = albums.Removed[0];
DeleteAlbum.Execute(cnn, removed);
albums.ConfirmDelete(removed);
Confirm current operations
bool allConfirmed = albums.ConfirmChanges();
Concrete item type
IEnumerable<AlbumRow> rows = existingRows;
TrackingList<AlbumRow> tracked = new(rows);
Application-defined list behavior can be supplied through ITrackingListContext<T>.