internal IObjectReaderFactory GetFactory(Type elementType, Type dataReaderType, object mapping,
                                          DataLoadOptions options, SqlExpression projection)
 {
     for (LinkedListNode <CacheInfo> node = list.First; node != null; node = node.Next)
     {
         if ((((elementType == node.Value.elementType) && (dataReaderType == node.Value.dataReaderType)) &&
              ((mapping == node.Value.mapping) && ShapesAreSimilar(options, node.Value.options))) &&
             SqlProjectionComparer.AreSimilar(projection, node.Value.projection))
         {
             list.Remove(node);
             list.AddFirst(node);
             return(node.Value.factory);
         }
     }
     return(null);
 }
        public IObjectReaderFactory Compile(SqlExpression expression, Type elementType)
        {
            //-------------------------SOURCE CODE--------------------------
            object identity = this.services.Context.Mapping.Identity;
            //--------------------------------------------------------------
            //var bf = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty;
            //object identity = typeof(MetaModel).InvokeMember("Identity", bf, null, services.Context.Mapping, null);
            //--------------------------------------------------------------
            DataLoadOptions      loadOptions = services.Context.LoadOptions;
            IObjectReaderFactory factory     = null;
            ReaderFactoryCache   data        = null;
            bool flag = SqlProjectionComparer.CanBeCompared(expression);

            if (flag)
            {
                data = (ReaderFactoryCache)Thread.GetData(cacheSlot);
                if (data == null)
                {
                    data = new ReaderFactoryCache(maxReaderCacheSize);
                    Thread.SetData(cacheSlot, data);
                }
                factory = data.GetFactory(elementType, dataReaderType, identity, loadOptions, expression);
            }
            if (factory == null)
            {
                var           gen          = new Generator(this, elementType);
                DynamicMethod method       = CompileDynamicMethod(gen, expression, elementType);
                var           t            = typeof(ObjectMaterializer <>).MakeGenericType(new[] { dataReaderType });
                var           delegateType = typeof(Func <,>).MakeGenericType(new[] { t, elementType });
                var           delegate2    = method.CreateDelegate(delegateType);

                factory = (IObjectReaderFactory)
                          Activator.CreateInstance(typeof(ObjectReaderFactory <,>).MakeGenericType(new[] { dataReaderType, elementType }),
                                                   BindingFlags.NonPublic | BindingFlags.Instance, null,
                                                   new object[] { delegate2, gen.NamedColumns, gen.Globals, gen.Locals }, null);
                if (flag)
                {
                    expression = new SourceExpressionRemover().VisitExpression(expression);
                    data.AddFactory(elementType, dataReaderType, identity, loadOptions, expression, factory);
                }
            }
            return(factory);
        }