Skip to content

TransformOnObservable mixes the order of changes in a given change set? #1007

@dwcullop

Description

@dwcullop

Discussed in #1000

Originally posted by paagamelo2 May 15, 2025
Ciao guys

I've been observing a weird behavior with TransformOnObservable. Namely, it mixes up the order of changes in a given change set.

This is a minimal test reproducing the issue:

private record Person(string Name, int Age);

[Test]
public void TransformOnObservableMixesTheOrderOfChangesInAGivenChangeSet()
{
    var sourceCache = new SourceCache<Person, string>(person => person.Name);

    // Cache emitted change sets
    var observedChangeSets = new List<IChangeSet<Person, string>>();
    using var subscription = sourceCache
        .AsObservableCache()
        .Connect()
        // Dummy observable that just returns the person
        .TransformOnObservable(Observable.Return)
        .Subscribe(changeSet =>
        {
            observedChangeSets.Add(changeSet);
        });

    sourceCache.Edit(innerCache =>
    {
        innerCache.AddOrUpdate(new Person("John", 30));
        innerCache.AddOrUpdate(new Person("Jane", 25));
        innerCache.AddOrUpdate(new Person("Doe", 40));
    });

    sourceCache.Edit(innerCache =>
    {
        innerCache.Clear();
        innerCache.AddOrUpdate(new Person("John", 32));
        innerCache.AddOrUpdate(new Person("Jane", 29));
        innerCache.AddOrUpdate(new Person("Doe", 18));
    });

    var lastChangeSet = observedChangeSets.Last();
    Debugger.Break();
}

In lastChangeSet I'd expect to find 3 Removes followed by 3 Adds. Instead, there are 3 Updates followed by 3 Removes; as if the AddOrUpdates were called before the Clear somehow.

image

Clearly, innerCache.Clear() makes little sense in this case. However, I think there might be real-life scenarios where an operation like that is legit. For instance, suppose sourceCache is representing the people living in a particular city selected by the user. If the user changes the city of interest, we may want to clear the cache and add people from the new city. If the key doesn't take into account the city (therefore allowing people from different cities to have the same key), any new people whose key was already in the cache will be incorrectly removed.

Currently, we're working around this by using EditDiff rather than Edit, which will emit an update for any item with the same key. But I'd be curious to know if this is a bug or whether I'm misusing Dynamic Data in any way.

Thanks
Lorenzo

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions