DynamicData.Snippets icon indicating copy to clipboard operation
DynamicData.Snippets copied to clipboard

Working with 2 dependent ObservableCaches

Open crosscourt opened this issue 7 years ago • 3 comments

Scenario: Tagging Items 2 caches: SourceCache<Item>, SourceCache<Tag> When item changes, it needs to go thru the list of tags to determine which one applies to it. Similarly, when tag changes, retagging needs to occur.

First not so reactive attempt:

var disposable = tagsCache.Connect().Flatten().Subscribe(change => { Tag tag = change.Current;

_itemCache.Edit(u => {
    if (change.Reason == ChangeReason.Remove)
    {
        foreach (Item item in _itemCache.Items.Where(b => b.Tags.Contains(tag)))
        {
            item.Tags.Remove(tag);
            u.AddOrUpdate(item);
        }
    }
    else
    {
        foreach (Item item in _itemCache.Items)
        {
            Tag existingTag = item.Tags.FirstOrDefault(t => t.Id == tag.Id);
            if (existingTag != null)
            {
                item.Tags.Remove(existingTag);
                u.AddOrUpdate(item);
            }

            bool applies = tag.Applies(item);
            if (applies)
            {
                item.Tags.Add(tag);
                u.AddOrUpdate(item);
            }
        }
    }
});

});

var disposable2 = _itemCache.Connect().WhereReasonsAre(ChangeReason.Add, ChangeReason.Update).Flatten().Subscribe(change => { Item item = change.Current;

instance.Tags.Connect().Flatten().Select(i => i.Current).Subscribe(tag =>
{
    if (!item.Tags.Contains(tag) && tag.Applies(item))
    {
        item.Tags.Add(tag);
    }
});

});

crosscourt avatar Sep 19 '17 10:09 crosscourt

From what I can understand you have a source collection with all the items and you want to filter the items into two separate caches?

In that case you can try something like this:

var sourceCacheA = tagSourceCache
                .Connect()
                .Filter(p => p.Title == "tagA")
                .AsObservableCache();
            
var sourceCacheB = tagSourceCache
                .Connect()
                .Filter(p => p.Title == "tagB")
                .AsObservableCache();

modplug avatar Sep 19 '17 11:09 modplug

sorry for my poor description. I have 2 separate caches (Items, Tags).

  1. When an item is added/changed/deleted from cache Items, i need to see which Tag will apply to it.
  2. When a Tag is added/changed/deleted, i need to tag the items that are applicable or remove an existing tag from the Items if it no longer applies.

Each tag has a condition, like "Item.Quantity > 10". So any changes to the Item or Tag Condition will need re-evaluation of everything.

crosscourt avatar Sep 20 '17 00:09 crosscourt

Maybe the ForEachChange() operator can come to the rescue

RolandPheasant avatar Sep 20 '17 06:09 RolandPheasant