MichaCo / CacheManager

CacheManager is an open source caching abstraction layer for .NET written in C#. It supports various cache providers and implements many advanced features.
http://cachemanager.michaco.net
Apache License 2.0
2.33k stars 457 forks source link

How to disable proxy to be created when using CacheManager backplaned by Azure redis? #322

Closed fzhangddt closed 3 years ago

fzhangddt commented 3 years ago

We use CacheManager with MicrosoftMemoryCache. Now we want to use CacheManager backplaned by Azure Redis but we run into the error below. I did some research, by default Entity Framework creates proxy, but we already set ProxyCreationEnabled to false in EF. How can I disable Cachemanager to use the proxy type? Please note the same code works with CacheManager with MicrosoftMemoryCache.

Settings: we use .net 4.7.2 and asp.net, hosted in azure app service. we use CacheManager.Core, Version=1.2.0.0 The DataSet class is marked with "DataContract", "DataMember". The code throwing the exception is: ICacheManager<DataSet>.Get(cacheKey)

InvalidOperationException: Could not load type 'System.Data.Entity.DynamicProxies.DataSet_323DE07FB58DB8B4465F5395947A376CF5E5D75B3D4A3A9D0D824AFF93033D30, EntityFrameworkDynamicProxies-DDTech.RPlus.Storage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Try add TypeCache.RegisterResolveType to resolve your type if the resolving continues to fail.]
   CacheManager.Core.Internal.TypeCache.GetType(String type) +586
   CacheManager.Redis.RedisValueConverter.Deserialize(RedisValue value, String valueType) +27
   CacheManager.Redis.RedisValueConverter.FromRedisValue(RedisValue value, String valueType) +24
   CacheManager.Redis.RedisCacheHandle`1.FromRedisValue(RedisValue value, String valueType) +399
   CacheManager.Redis.RedisCacheHandle`1.GetCacheItemAndVersion(String key, String region, Int32& version) +1546
   CacheManager.Redis.RedisCacheHandle`1.GetCacheItemInternal(String key, String region) +21
   CacheManager.Core.BaseCacheManager`1.GetCacheItemInternal(String key, String region) +200
   CacheManager.Core.Internal.BaseCache`1.Get(String key) +22
   DDTech.RPlus.Storage.SqlServer.Caching.DataSetCachingRepository.GetById(Int32 id)

Thanks a lot!

MichaCo commented 3 years ago

Memory cache works in memory and might, be coincidence work even with highly volatile objects like EF proxies. It is a bad idea to cache those in general. A distributed cache like Redis require serialization to binary or string, which doesn't work well with dynamic objects.

EF Proxies are usually used to lazy load dependencies and might not be real objects. Just don't cache them, load your data into POCOs and cache that.