Table of Contents

Tracking

One editable item

public record Album(int Id, string Title);

Album original = new(12, "Blue");
IRuntimeTrackingItem<Album> edit = RuntimeTracking.Default<Album>().Create(original);

edit.Set(nameof(Album.Title), "Kind of Blue");

foreach (TrackingChange change in edit.GetChanges())
    Console.WriteLine($"{change.Name} {change.OriginalValue} -> {change.Value}");

GetChanges() enumerates the differences that exist now between accepted and edited values.

Editable items

Typed contract

public interface IAlbumEdit : IRuntimeTrackingItem<Album>
{
    int Id { get; }
    string Title { get; set; }
}

RuntimeTrackingOptions<Album> options = RuntimeTracking.CreateOptions<Album, IAlbumEdit>();
IAlbumEdit edit = options.GetRegistration<IAlbumEdit>().Create(original);

edit.Title = "Kind of Blue";

The generated CLR type implements the contract while the same runtime tracking state remains available through IRuntimeTrackingItem<Album>.

Runtime tracking

Structural list changes

List<Album> existingAlbums = cnn.Query<List<Album>>("SELECT AlbumId AS Id, Title FROM albums ORDER BY AlbumId");
TrackingList<Album> albums = new(existingAlbums);

albums.Add(new Album(0, "New album"));
albums.RemoveAt(0);

Console.WriteLine(albums.AddedCount);
Console.WriteLine(albums.RemovedCount);

The list can also contain generated editable items.

TrackingList<IRuntimeTrackingItem<Album>> albums = existingAlbums.ToTrackingList();

IRuntimeTrackingItem<Album> added = albums.AddNew();
added.Set(nameof(Album.Title), "New album");

Tracking lists

Binding

using Rinku.Tracking.Binding;

BindingTrackingList<IRuntimeTrackingItem<Album>> albums = existingAlbums.ToBindingList();

Binding

Validation and metadata

RuntimeTrackingOptions<Album> options = RuntimeTracking.CreateOptions<Album, IAlbumEdit>();

options.Validate<Album, IAlbumEdit>(static edit => !string.IsNullOrWhiteSpace(edit.Title));
options.Metadata<Album, string[]>();

Validation and metadata

Persist and confirm

static readonly QueryCommand UpdateAlbum = new("UPDATE albums SET Title = @Title WHERE AlbumId = @Id");

if (edit.HasChanges())
{
    UpdateAlbum.Execute(cnn, edit);
    edit.ConfirmEdit();
}

Persistence