In ASP.NET Core, in-memory caching is a technique used to
store data within the application's memory. This cached data is readily
accessible to subsequent requests, which can significantly improve the
performance of the application by avoiding expensive operations such as
repeated database queries or complex calculations.
Create an webapi project named it InMemoryCaching. We will
use database first approach.
In appsetting set database configutation:
,
"ConnectionStrings": {
"DBConnectionString": "Server=DESKTOP-M80VO7A;Database=EmployeeDB;Trusted_Connection=True;MultipleActiveResultSets=true;
TrustServerCertificate=True;Integrated Security=SSPI;
TrustServerCertificate=True; MultipleActiveResultSets=true;"
}
Create context file: EmployeeDbContext
public partial class EmployeeDbContext :
DbContext
{
public EmployeeDbContext(DbContextOptions<EmployeeDbContext>
options)
: base(options)
{
}
}
In Program.cs file:
builder.Services.AddDbContext<EmployeeDbContext>(options
=>
options.UseSqlServer(builder.Configuration.GetConnectionString("DBConnectionString")));
builder.Services.AddMemoryCache();
we need to download some nuget packages like SqlServer, Tools, Design
etc.
Open package manager console and run the command:
Scaffold-DbContext -Connection Name=DBConnectionString
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models –force
Create controller named it EmployeeController
Write the code below in the controller:
private readonly EmployeeDbContext
_context;
private readonly IMemoryCache _cache;
public
EmployeeController(EmployeeDbContext context, IMemoryCache cache)
{
_context = context;
_cache = cache;
}
[HttpGet]
public async Task<IActionResult>
GetAll()
{
var products = await _context.Employees.ToListAsync();
return Ok(products);
}
[HttpGet]
[Route("GetAllCache")]
public async Task<IActionResult>
GetAllCache()
{
var cacheKey = "GET_ALL_EMPLOYEES";
// If data found in cache, return cached data
if (_cache.TryGetValue(cacheKey, out List<Employee> Employees))
{
return Ok(Employees);
}
// If not found, then fetch data from database
Employees = await _context.Employees.ToListAsync();
// Add data in cache
_cache.Set(cacheKey, Employees);
return Ok(Employees);
}
Open post man and test the controller, when we run get all
we get the result below:
When we run get all cache:
To cache data for the exact time, we can
use the AbsoluteExpiration setting. In the following code snippet, the
AbsoluteExpiration is set to 5 minutes, which means no matter how frequently
our cached data is accessed, it will flush after 5 minutes.
var cacheOptions = new MemoryCacheEntryOptions()
{
AbsoluteExpiration =
DateTime.Now.AddMinutes(5)
};
_cache.Set(cacheKey,
Employees, cacheOptions);
We can also use the SlidingExpiration setting which allows us to remove cached items which are not
frequently accessed. In the example below, I set it to 5 minutes which means
that data will remove from the cache only if it is not accessed in the last 5
minutes.
var cacheOptions = new MemoryCacheEntryOptions()
{
SlidingExpiration =
TimeSpan.FromMinutes(5)
};
_cache.Set(cacheKey,
Employees, cacheOptions);
If our data is accessed more frequently
than our sliding expiration time, then we will end up in a situation where our
data will never expire. We can resolve this problem by following code:
var cacheOptions = new MemoryCacheEntryOptions()
{
SlidingExpiration = TimeSpan.FromMinutes(5),
AbsoluteExpiration =
DateTime.Now.AddMinutes(60)
};
_cache.Set(cacheKey,
Employees, cacheOptions);
We can also set the priority of the
cached items to keep high priority items in cache during a memory pressure
triggered cleanup. By default, all items in the cache have Normal priority but
we are allowed to set Low, Normal, High, and NeverRemove options as well.
var cacheOptions = new
MemoryCacheEntryOptions()
{
AbsoluteExpiration = DateTime.Now.AddMinutes(60),
Priority = CacheItemPriority.High
};
_cache.Set(cacheKey, Employees, cacheOptions);
Github: https://github.com/itsjubayer/InMemoryCaching.git
No comments:
Post a Comment