locked
How to update/remove certain items in a cache object? RRS feed

  • Question

  • User-2089506584 posted

    Hello,

    How to update/remove certain items in a cache object using IMemoryCache?

    When getting cache object, I do below...

    [HttpGet]
    public IEnumerable<string> Get()
    {
    string key = "ALLCar-Key";
    
    IList<CarModel> carModelCached = _cache.GetOrCreate(key, entry =>
    {
    var sampleRecordFromDB = new List<CarModel>
    {
    new CarModel() { Id = 10, Name = "Hyundai", Year = 1998 },
    new CarModel() { Id = 20, Name = "GMC", Year = 2013 },
    new CarModel() { Id = 30, Name = "Subaru", Year = 2019 },
    };
    
    return sampleRecordFromDB.ToList();
    });
    
    
    return carModelCached;
    }


    but, if after I do an update/insert, I have to refetch from DB and insert back the updated data to cache.

    [HttpPost]
    public void Post(List<CarModel> car)
    {
    string key = "ALLCar-Key";
    
    //fetch from db (removed for brevity...)
    
    var sampleRecordFromDB = new List<CarModel>
    {
    new CarModel() { Id = 10, Name = "Hyundai", Year = 1998 },
    new CarModel() { Id = 20, Name = "GMC", Year = 2020 }, //<<<<------UPDATED VALUE HERE
    new CarModel() { Id = 30, Name = "Subaru", Year = 2019 },
    };
    
    MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
    {
    AbsoluteExpiration = DateTime.Now.AddDays(1)
    };
    
    _cache.Set(key, sampleRecordFromDB.ToList(), options);
    }


    My data runs around 150K item, and doing just a simple update to one item then do the cache update is too expensive (performance wise - slow).

    Is there a way that I could read from cache and do a single item update/insert from within the cache object?


    Thanks,

    Saturday, April 11, 2020 12:47 PM

Answers

  • User475983607 posted

    In your code below, if i'm not mistaken it's hitting the db which uses LINQ?

    sampleRecordFromDB.FirstOrDefault(m => m.Id == 20).Year = 2020;

    No.  LINQ also works with collections.

    Is there an expression or equivalent query to do the CRUD within a cache collection like below?

    var updatedCache = _cache.Get(key).Where(s => s.Id == 20).Year = 2020;
    
    

    I've already explained what to do.  For the second time.... you cached a collection.  First you need to get the collection from the cache.  Then you can update the collection using LINQ.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, April 12, 2020 4:14 PM

All replies

  • User475983607 posted

    How to update/remove certain items in a cache object using IMemoryCache?

    Pretty simple.  The tricky part with your design is the cached item is a collection.  Get the collection by key.   Update/Remove the collection item using standard LINQ syntax.  

    static void Main(string[] args)
    {
        var sampleRecordFromDB = new List<CarModel>
        {
            new CarModel() { Id = 10, Name = "Hyundai", Year = 1998 },
            new CarModel() { Id = 20, Name = "GMC", Year = 2019 }, 
            new CarModel() { Id = 30, Name = "Subaru", Year = 2019 }
        };
    
        sampleRecordFromDB.FirstOrDefault(m => m.Id == 20).Year = 2020;
    
        foreach(var item in sampleRecordFromDB)
        {
            Console.WriteLine($"{item.Id}\t{item.Name}\t{item.Year}");
        }
    }

    Results

    10      Hyundai 1998
    20      GMC     2020
    30      Subaru  2019

    Saturday, April 11, 2020 7:05 PM
  • User-2089506584 posted

    Update/Remove the collection item using standard LINQ syntax.  

    Hi mgebhard,

    What I meant was to update/remove the items inside the cache object collection by not filtering the db. Is that even possible, like read the cache object then insert items within that cache object?

    Thanks,

    Sunday, April 12, 2020 2:54 PM
  • User475983607 posted

    imperialx

    What I meant was to update/remove the items inside the cache object collection by not filtering the db. Is that even possible, like read the cache object then insert items within that cache object?

    And that's exactly what the code does.  It's unclear why you think there is database access in the sample code.  Clearly, the collection is cached.  The collection might have originated from a DB but that does not matter. 

    Sunday, April 12, 2020 3:03 PM
  • User-2089506584 posted

    It's unclear why you think there is database access in the sample code. 

    Hi mgebhard,

    In your code below, if i'm not mistaken it's hitting the db which uses LINQ?

    sampleRecordFromDB.FirstOrDefault(m => m.Id == 20).Year = 2020;
    Sunday, April 12, 2020 3:10 PM
  • User-2089506584 posted

    Is there an expression or equivalent query to do the CRUD within a cache collection like below?

    var updatedCache = _cache.Get(key).Where(s => s.Id == 20).Year = 2020;

    Sunday, April 12, 2020 3:16 PM
  • User475983607 posted

    In your code below, if i'm not mistaken it's hitting the db which uses LINQ?

    sampleRecordFromDB.FirstOrDefault(m => m.Id == 20).Year = 2020;

    No.  LINQ also works with collections.

    Is there an expression or equivalent query to do the CRUD within a cache collection like below?

    var updatedCache = _cache.Get(key).Where(s => s.Id == 20).Year = 2020;
    
    

    I've already explained what to do.  For the second time.... you cached a collection.  First you need to get the collection from the cache.  Then you can update the collection using LINQ.  

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, April 12, 2020 4:14 PM
  • User-2089506584 posted

    I've already explained what to do.  For the second time.... you cached a collection.  First you need to get the collection from the cache.  Then you can update the collection using LINQ.  

    Thank You a million! and sorry for the confusion. Your solution works!

    Cheers!

    Monday, April 13, 2020 1:52 AM