Share via


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

Question

Saturday, April 11, 2020 12:47 PM

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,

All replies (7)

Sunday, April 12, 2020 4:14 PM âś…Answered

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.  


Saturday, April 11, 2020 7:05 PM

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

Sunday, April 12, 2020 2:54 PM

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 3:03 PM

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:10 PM

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:16 PM

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;

Monday, April 13, 2020 1:52 AM

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!