Ejemplo n.º 1
0
        public IObjectReaderFactory Compile(SqlExpression expression, Type elementType)
        {
            object                   mapping = this.services.Context.Mapping.Identity;
            DataLoadOptions          options = this.services.Context.LoadOptions;
            IObjectReaderFactory     factory = null;
            ObjectReaderFactoryCache cache   = null;
            bool canBeCompared = SqlProjectionComparer.CanBeCompared(expression);

            if (canBeCompared)
            {
                cache = (ObjectReaderFactoryCache)Thread.GetData(cacheSlot);
                if (cache == null)
                {
                    cache = new ObjectReaderFactoryCache(maxReaderCacheSize);
                    Thread.SetData(cacheSlot, cache);
                }
                factory = cache.GetFactory(elementType, this.dataReaderType, mapping, options, expression);
            }
            if (factory == null)
            {
                DynamicTypeGenerator gen = new DynamicTypeGenerator(this, elementType);
#if DEBUG
                if (ObjectReaderCompiler.CaptureModule != null)
                {
                    this.CompileCapturedMethod(gen, expression, elementType);
                }
#endif
                DynamicMethod dm            = this.CompileDynamicMethod(gen, expression, elementType);
                Type          fnMatType     = typeof(Func <,>).MakeGenericType(typeof(ObjectMaterializer <>).MakeGenericType(this.dataReaderType), elementType);
                var           fnMaterialize = (Delegate)dm.CreateDelegate(fnMatType);

                Type factoryType = typeof(ObjectReaderFactory <,>).MakeGenericType(this.dataReaderType, elementType);
                factory = (IObjectReaderFactory)Activator.CreateInstance(
                    factoryType, BindingFlags.Instance | BindingFlags.NonPublic, null,
                    new object[] { fnMaterialize, gen.NamedColumns, gen.Globals, gen.Locals }, null
                    );

                if (canBeCompared)
                {
                    expression = new SourceExpressionRemover().VisitExpression(expression);
                    cache.AddFactory(elementType, this.dataReaderType, mapping, options, expression, factory);
                }
            }
            return(factory);
        }
 internal IObjectReaderFactory GetFactory(Type elementType, Type dataReaderType, object mapping, DataLoadOptions options, SqlExpression projection)
 {
     for (LinkedListNode <CacheInfo> info = this.list.First; info != null; info = info.Next)
     {
         if (elementType == info.Value.elementType &&
             dataReaderType == info.Value.dataReaderType &&
             mapping == info.Value.mapping &&
             DataLoadOptions.ShapesAreEquivalent(options, info.Value.options) &&
             SqlProjectionComparer.AreSimilar(projection, info.Value.projection)
             )
         {
             // move matching item to head of list to reset its lifetime
             this.list.Remove(info);
             this.list.AddFirst(info);
             return(info.Value.factory);
         }
     }
     return(null);
 }