[SOLVED] Is LINQ querying the database, making my caching useless?

Issue

So I have some code like this:

var attribute = _genericAttributeService
    .GetAttributesForEntity(_workContext.CurrentCustomer.Id, "Customer")
    .FirstOrDefault(x => x.Key == "CompareProducts");

The GetAttributesForEntity looks like this:

public virtual IList<GenericAttribute> GetAttributesForEntity(int entityId, string keyGroup)
{
    return _cacheManager.Get(string.Format(GENERICATTRIBUTE_KEY, entityId, keyGroup), () =>
    {
        var query = from ga in _genericAttributeRepository.Table
                            where ga.EntityId == entityId &&
                            ga.KeyGroup == keyGroup
                            select ga;
        var attributes = query.ToList();
        return attributes;
    });
}

So it’s using caching to reduce db queries.

Is the FirstOrDefault() now querying the returned list, or is another database query made?
Would be good to know exactly what’s happening here.

Solution

Is the FirstOrDefault() now querying the returned list, or is another
database query made?

Short answer:

FirstOrDefault will query the cached list.

Long answer:

_cacheManager will use the provided arguments (entityId, keyGroup) to retrieve the list from the cache.

If the element is not in the cache, it will execute the lambda to retrieve the data from the database and will store the results with key (entityId, keyGroup).

It will store the complete List<>. Pay attention to the statement:

var attributes = query.ToList();

So, if you repeat a call to GetAttributesForEntity, using the same parameters, you will get the stored results.

Note: NopCommerce implements different cache levels, and cache invalidation procedures, which I will not dive into at this moment.

Answered By – Marco Regueira

Answer Checked By – Pedro (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *