Cache in memory specific queries
Complement for Infoware.UnitOfWork
Usage:
public class UserService
{
private readonly IEFCoreMemoryCache _memoryCache;
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository, IEFCoreMemoryCache memoryCache)
{
_userRepository = userRepository;
_memoryCache = memoryCache;
}
public async Task<IPagedList<UserView>> GetAll(int page, int rowsPerPage)
{
string cacheKey = "user_all";
var query = from user in _userRepository.GetAll()
select new UserView()
{
Id = user.Id,
Name = user.Name
};
return await query.CacheableTagWith(cacheKey, TimeSpan.FromMinutes(15))
.ToPagedListAsync(pageIndex: page, pageSize: rowsPerPage, cancellationToken: cancellationToken);
}
}
query.Cacheable interrupts the query and tries to check if there is a previous execution cached with cacheKey; otherwise, the query is executed and cached with the configured TimeSpan.
If you want to invalidate the cache, e.g. if your repository add a new User, you must to execute RemoveKeysStartsWith method
public class UserRepository<TContext> : Repository<TContext, User>
{
private readonly IEFCoreMemoryCache _memoryCache;
public UserRepository(IUserRepository userRepository)
{
_memoryCache = memoryCache;
}
public override User Insert(User entity)
{
_memoryCache.RemoveKeysStartsWith("user_");
return base.Insert(User);
}
}
If you want to ensure to invalidate cache when changes are saved execute RemoveAllPendingKeys in SaveChanges, and in each insert create a pending remove with PendingRemoveKeysStartsWith
public class UserRepository<TContext> : Repository<TContext, User>
{
private readonly IEFCoreMemoryCache _memoryCache;
public UserRepository(IUserRepository userRepository)
{
_memoryCache = memoryCache;
}
public override User Insert(User entity)
{
_memoryCache.AddPendingRemoveKeysStartsWith("user_");
return base.Insert(User);
}
}
public class DocumentosContext : DbContext
{
...
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
var result = await base.SaveChangesAsync(cancellationToken);
_memoryCache.RemoveAllPendingKeys();
return result;
}
}