Browse Source

`EnableTracking` if the `entity` has `ObjectExtensionInfo`.

The `FillExtraPropertiesForTrackedEntities` method of `AbpDbContext` required `Change Tracking.`
pull/19394/head
maliming 3 years ago
parent
commit
7769227b4f
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 42
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs
  2. 24
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs
  3. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs

42
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheBase.cs

@ -1,8 +1,10 @@
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Uow;
namespace Volo.Abp.Domain.Entities.Caching;
@ -26,32 +28,52 @@ public abstract class EntityCacheBase<TEntity, TEntityCacheItem, TKey> :
Cache = cache;
UnitOfWorkManager = unitOfWorkManager;
}
public virtual async Task<TEntityCacheItem?> FindAsync(TKey id)
{
return await Cache.GetOrAddAsync(
id,
async () => MapToCacheItem(await Repository.FindAsync(id))!
);
async () =>
{
if (HasObjectExtensionInfo())
{
Repository.EnableTracking();
}
return MapToCacheItem(await Repository.FindAsync(id))!;
});
}
public virtual async Task<TEntityCacheItem> GetAsync(TKey id)
{
return (await Cache.GetOrAddAsync(
id,
async () => MapToCacheItem(await Repository.GetAsync(id))!
))!;
async () =>
{
if (HasObjectExtensionInfo())
{
Repository.EnableTracking();
}
return MapToCacheItem(await Repository.GetAsync(id))!;
}))!;
}
protected virtual bool HasObjectExtensionInfo()
{
return typeof(IHasExtraProperties).IsAssignableFrom(typeof(TEntity)) &&
ObjectExtensionManager.Instance.GetOrNull(typeof(TEntity)) != null;
}
protected abstract TEntityCacheItem? MapToCacheItem(TEntity? entity);
public async Task HandleEventAsync(EntityChangedEventData<TEntity> eventData)
{
if (eventData is EntityCreatedEventData<TEntity>)
{
return;
}
/* Why we are using double remove:
* First Cache.RemoveAsync drops the cache item in a unit of work.
* Some other application / thread may read the value from database and put it to the cache again
@ -59,12 +81,12 @@ public abstract class EntityCacheBase<TEntity, TEntityCacheItem, TKey> :
* The second Cache.RemoveAsync drops the cache item after the database transaction is complete.
* Only the second Cache.RemoveAsync may not be enough if the application crashes just after the UOW completes.
*/
await Cache.RemoveAsync(eventData.Entity.Id);
if(UnitOfWorkManager.Current != null)
{
await Cache.RemoveAsync(eventData.Entity.Id, considerUow: true);
}
}
}
}

24
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheServiceCollectionExtensions.cs

@ -16,13 +16,8 @@ public static class EntityCacheServiceCollectionExtensions
DistributedCacheEntryOptions? cacheOptions = null)
where TEntity : Entity<TKey>
{
services
.TryAddTransient<
IEntityCache<TEntity, TKey>,
EntityCacheWithoutCacheItem<TEntity, TKey>
>();
services
.TryAddTransient<EntityCacheWithoutCacheItem<TEntity, TKey>>();
services.TryAddTransient<IEntityCache<TEntity, TKey>, EntityCacheWithoutCacheItem<TEntity, TKey>>();
services.TryAddTransient<EntityCacheWithoutCacheItem<TEntity, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options =>
{
@ -43,13 +38,8 @@ public static class EntityCacheServiceCollectionExtensions
where TEntity : Entity<TKey>
where TEntityCacheItem : class
{
services
.TryAddTransient<
IEntityCache<TEntityCacheItem, TKey>,
EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>
>();
services
.TryAddTransient<EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>>();
services.TryAddTransient<IEntityCache<TEntityCacheItem, TKey>, EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>>();
services.TryAddTransient<EntityCacheWithObjectMapper<TEntity, TEntityCacheItem, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options =>
{
@ -65,11 +55,7 @@ public static class EntityCacheServiceCollectionExtensions
where TEntity : Entity<TKey>
where TEntityCacheItem : class
{
services
.TryAddTransient<
IEntityCache<TEntityCacheItem, TKey>,
EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>
>();
services.TryAddTransient<IEntityCache<TEntityCacheItem, TKey>, EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>>();
services.TryAddTransient<EntityCacheWithObjectMapperContext<TObjectMapperContext, TEntity, TEntityCacheItem, TKey>>();
services.Configure<AbpDistributedCacheOptions>(options =>

2
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Caching/EntityCacheWithoutCacheItem.cs

@ -20,6 +20,4 @@ public class EntityCacheWithoutCacheItem<TEntity, TKey> :
{
return entity;
}
}

Loading…
Cancel
Save