0

I am trying to cache my entities returned from repositories. I am intercepting calls to repository methods, so that I can check if the requested data exist in cache. But, since I am intercepting the method call, I can't obtain the real entity type, as you may guess I get an EF proxy type. So when I put it to cache, I am not putting the real entity, instead I am putting a subclass of it.

As I recall Nhibernate has some utility to initialize proxy immediately. Can we do it in EF 6? How can I get the underlying entity in here?

Here is some of my code to clarify my need. I am using Castle Interceptors by the way.

public class CacheInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
                if (IsReturnTypeCacheable(invocation.Method.ReturnType))
                {
                    string cacheKey = this.CreateCacheKey(invocation.Method.Name, invocation.Arguments);

                    object returnValue = this.GetFromCache<object>(cacheKey);

                    if (returnValue != null)
                    {
                        invocation.ReturnValue = returnValue;
                        return;
                    }
                    else
                    {
                        invocation.Proceed();

                        object actualValue = invocation.ReturnValue;

                        Type proxyType = invocation.ReturnValue.GetType();
                        Type pocoType = proxyType.BaseType;

                        var dataInstance = Activator.CreateInstance(pocoType);

                        dataInstance = invocation.ReturnValue;

                        this.PutToCache(cacheKey, dataInstance);// This puts the proxy type to cache, not underlying POCO...
                    }
                }
                else
                {
                    invocation.Proceed();
                }
        }

        private bool IsReturnTypeCacheable(Type type)
        {
            //some custom checks
        }

        public T GetFromCache<T>(string cacheKey) where T : class
        {
            IRedisNativeClient redisClient = new RedisNativeClient("myredis");

            byte[] obj = redisClient.Get(cacheKey);

            if (obj == null) return null;

            return Serializer.Deserialize<T>(obj);
        }

        public void PutToCache(string cacheKey, object value)
        {
            if (value == null) return;

            IRedisNativeClient redisClient = new RedisNativeClient("myredis");

            redisClient.Set(cacheKey, Serializer.Serialize(value));
        }

        public string CreateCacheKey(string method, object[] arguments)
        {
            //creates cache key
        }
    }
ayk
  • 1,407
  • 2
  • 19
  • 26
  • `DbSet.Create` creates proxies if the entity class meets the conditions for proxy creation. As an aside, I don't understand why you cache entities per method call. Now each method call can potentially get different entity instances. I don't think that's the idea of a cache. – Gert Arnold Feb 26 '14 at 09:34
  • I just want to do opposite of DbSet.Create. I want to create entity from a given proxy. On caching per method call, I just couldn't come up with a better idea. I looked up for 2nd level cache for EF 6. But I couldn't find anything. I don't cache all my methods here, I have a filter too. I just cache catalog-like data, and don't touch transactional data.. – ayk Feb 26 '14 at 12:54
  • The other way around is impossible because the proxy inherits the base type, it does not *contain* the type in any way. So you need to know the base type to cast the compile-time type of a proxy - chicken-egg problem. As for caching, did you see this: http://entityframework.codeplex.com/discussions/428698, or this: http://blogs.msdn.com/b/jkowalski/archive/2009/06/11/tracing-and-caching-in-entity-framework-available-on-msdn-code-gallery.aspx – Gert Arnold Feb 26 '14 at 13:10
  • I know about Jaroslaw Kowalski's caching provider, but it seems old. It uses ObjectContext. Can it be used with Ef6? – ayk Feb 26 '14 at 13:31

0 Answers0