Reputation: 382
I have inherited a VisualStudio 2019 C# DevExpress Blazor XPO web project with SQL Server database running under IIS and have issues with page data always being cached.
The project itself is defined as a .NET 5.0 Console application built for 64bit operation.
I am not experienced in DevExpress or Blazor and am learning on the go, I have been able to run the application in debug under IIS Express using visual studio.
I have tried refreshing the DxDataGrid which is displaying the data, but by adding logging to a file I have determined that the data returned from the query of the database isn't changing. I have confirmed using SQL Server management studio that the changes have been applied to the actual database, hence I believe I am getting cached data.
I believe this caching is related to the underlying UnitOfWork caching, but no matter what I try the data is always cached and I cannot get the changes to display unless I do an actual web page refresh.
The base class contains a UnitOfWork called readUniOfWork, this is used for fetching all of the data for the class. This readUnitOfWork is created when the class is instantiated and is a readonly property of the class.
public Task<IQueryable<T>> Get(System.Linq.Expressions.Expression<System.Func<T, bool>> criteria = null)
{
var query = (IQueryable<T>)readUnitOfWork.Query<T>();
//IQueryable<T> query = new XPQuery<T>(readUnitOfWork);
if (criteria != null)
query = query.Where(criteria);
return Task.FromResult(query);
}
The update function creates a new UnitOfWork for each update
public async Task<T> Update(T item, IDictionary<string, object> values)
{
try
{
using (UnitOfWork uow = CreateModificationUnitOfWork())
{
item = uow.GetObjectByKey<T>(item.Oid);
PopulateObjectHelper.PopulateObject(item, values);
await uow.CommitChangesAsync();
}
return await readUnitOfWork.GetObjectByKeyAsync<T>(item.Oid, true);
}
catch (Exception e)
{
_Logger.Error(e);
throw;
}
}
I tried changing the Update function to also use the same UnitOfWork "readUnitOfWork" but this did not change the behaviour. I could debug and see the changes occurring in the item data and see these saved to the database, but when the read occurs, the data is still the old data. A refresh of the page correctly returns the updated data.
Would welcome any suggestions or pointing to an example project.
Upvotes: 0
Views: 304
Reputation: 382
I found the answer to this issue and am posting here in case others find the same issue and this can be of help.
Delving into the code, I found that all the persistent data stores had OptimisticLocking set to false.
[Persistent("qCustomer"), OptimisticLocking(false)]
Searching on DevExpress, I found "Without Optimistic Locking, XPO cannot determine whether or not a specific object was modified." This means that the data is always loaded from the cache.
I then found "All the persistent objects loaded using the current session are stored in the Identity Map. The DropIdentityMap method invalidates the object references, enabling the garbage collector to free up the space which is occupied by the session object at a later time.
Calling the DropIdentityMap method has the same effect as reconnecting a session."
Changing the Update function to call DropIdentityMap after the records were updated fixed my issue.
using (UnitOfWork uow = CreateModificationUnitOfWork())
{
item = uow.GetObjectByKey<T>(item.Oid);
PopulateObjectHelper.PopulateObject(item, values);
await uow.CommitChangesAsync();
}
// Tell XPO to reload from the database by voiding the current store
readUnitOfWork.DropIdentityMap();
Upvotes: 0