Exclude certain entities from second-level caching

2019-08-10 03:42发布

问题:

I'm using EFCache to provide 2nd-level caching in my EF context.

I ran into a problem, where one of my entities is connected to a view which provides row-level security. So this view filters rows based on some parameters. When using 2nd-level cache, all users will get the same result!

I'm looking for a way to exclude certain entities from caching, any help is welcome.

This is my caching configuration:

class CacheConfiguration : DbConfiguration
{
    public CacheConfiguration()
    {
        var transactionHandler = new CacheTransactionHandler(new InMemoryCache());

        AddInterceptor(transactionHandler);

        var cachingpolicy = new cachingpolicy();

        Loaded +=
            (sender, e) => e.ReplaceService<DbProviderServices>(
                (s, _) => new CachingProviderServices(s, transactionHandler, cachingPolicy));
    }
}

回答1:

I found the answer in this blog post.

In order to exclude some entities, you need to create a caching policy and drive a class from CachingPolicy.

After overriding CanBeCached method, you can return false to prevent caching.

This is my working code:

class CacheConfiguration : DbConfiguration
{
    public CacheConfiguration()
    {
        var transactionHandler = new CacheTransactionHandler(new InMemoryCache());

        AddInterceptor(transactionHandler);

        //var cachingPolicy = new CachingPolicy();
        var cachingPolicy = new myCachingPolicy();

        Loaded +=
            (sender, e) => e.ReplaceService<DbProviderServices>(
                (s, _) => new CachingProviderServices(s, transactionHandler, cachingPolicy));
    }
}

public class myCachingPolicy : CachingPolicy
{
    protected override bool CanBeCached(System.Collections.ObjectModel.ReadOnlyCollection<System.Data.Entity.Core.Metadata.Edm.EntitySetBase> affectedEntitySets, string sql, IEnumerable<KeyValuePair<string, object>> parameters)
    {
        string[] excludedEntities = {
            "permView1",
            "permView2",
            "permView3"};

        if (affectedEntitySets.Where(x => excludedEntities.Contains(x.Table)).Any())
        {
            return false;
        }
        else
        {
            return base.CanBeCached(affectedEntitySets, sql, parameters);
        }
    }
}