VahidN / EFSecondLevelCache.Core

Entity Framework Core Second Level Caching Library
Apache License 2.0
326 stars 50 forks source link

Redis cache issue with Entity framework model classes - dotnet core 3.1 #66

Open Marc-Albert opened 4 years ago

Marc-Albert commented 4 years ago

Summary of the issue

First call insert the value into redis successfully but the second one always display the below error;

"Could not load type 'Castle.Proxies.OrganizationProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Try add TypeCache.RegisterResolveType to resolve your type if the resolving continues to fail."

On the other hand, if I use a DTO in my select statement then no problem occurs.

Note: I used the redis configuration exactly as explained. I have a feeling that this issue is happening with FirstOrDefault() & First()

Environment

.NET Core SDK version: 3.1.0
Microsoft.EntityFrameworkCore version: 3.1.0
EFSecondLevelCache.Core version: 2.9.1

Example code/Steps to reproduce:


return _context.Organization.Where(o => o.OrganizationId == orgId).Cacheable().FirstOrDefault();

## Output:

Exception message: Message = "Could not load type 'Castle.Proxies.OrganizationProxy, DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Try add TypeCache.RegisterResolveType to resolve your type if the resolving continues to fail."

Full Stack trace: " at CacheManager.Core.Internal.TypeCache.GetType(String type)\r\n at CacheManager.Redis.RedisValueConverter.CacheManager.Redis.IRedisValueConverter.FromRedisValue(RedisValue value, String type)\r\n at CacheManager.Redis.RedisCacheHandle1.FromRedisValue(RedisValue value, String valueType)\r\n at CacheManager.Redis.RedisCacheHandle1.GetCacheItemAndVersion(String key, String region, Int32& version)\r\n at CacheManager.Redis.RedisCacheHandle1.GetCacheItemInternal(String key, String region)\r\n at CacheManager.Redis.RedisCacheHandle1.GetCacheItemInternal(String key)\r\n at CacheManager.Core.Internal.BaseCache1.GetCacheItem(String key)\r\n at CacheManager.Core.BaseCacheManager1.GetCacheItemInternal(String key, String region)\r\n at CacheManager.Core.BaseCacheManager1.GetCacheItemInternal(String key)\r\n at CacheManager.Core.Internal.BaseCache1.GetCacheItem(String key)\r\n at CacheManager.Core.Internal.BaseCache`1.Get(String key)\r\n at EFSecondLevelCache.Core.EFCacheServiceProvider.GetValue(String cacheKey)\r\n at EFSecondLevelCache.Core.EFMaterializer.readFromCache[T](Expression expression)\r\n at "

VahidN commented 4 years ago

EF Core uses Castle.Proxies to support lazy loading. Also other libraries such as AutoMapper are using it too. Sometimes it means you have initialized auto-mapper more than once or you are not referencing correct dependencies in different libraries of your project (For using lazy loading, the package Microsoft.EntityFrameworkCore.Proxies needs to be added to the project references.). Also SecondLevelCache always uses eager loading. So if you have enabled lazy loading, don't use it with this library.

Marc-Albert commented 4 years ago

but this is not happening when using .ToList()

VahidN commented 4 years ago

I can't reproduce your issue. To test it, First I enabled the redis provider and then called the https://localhost:5001/ which maps to the FirstOrDefaultAsync sample. It works.