コード例 #1
0
		private void CompileCapturedMethod(DynamicTypeGenerator gen, SqlExpression expression, Type elementType)
		{
			TypeBuilder tb = ObjectReaderCompiler.CaptureModule.DefineType("reader_type_" + ObjectReaderCompiler.GetNextId());
			MethodBuilder mb = tb.DefineMethod(
				"Read_" + elementType.Name,
				MethodAttributes.Static | MethodAttributes.Public,
				CallingConventions.Standard,
				elementType,
				new Type[] { typeof(ObjectMaterializer<>).MakeGenericType(this.dataReaderType) }
				);
			gen.GenerateBody(mb.GetILGenerator(), (SqlExpression)SqlDuplicator.Copy(expression));
			tb.CreateType();
		}
コード例 #2
0
		private DynamicMethod CompileDynamicMethod(DynamicTypeGenerator gen, SqlExpression expression, Type elementType)
		{
			Type objectReaderType = typeof(ObjectMaterializer<>).MakeGenericType(this.dataReaderType);
			DynamicMethod dm = new DynamicMethod(
				"Read_" + elementType.Name,
				elementType,
				new Type[] { objectReaderType },
				true
				);
			gen.GenerateBody(dm.GetILGenerator(), expression);
			return dm;
		}
コード例 #3
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;
		}