示例#1
0
        internal static bool TryGetLoaderCache <T>(IDataRecord reader, Cache.LoaderCacheKey cacheKey, out Cache.LoaderCacheValue cacheValue)
        {
            if (Cache.Loaders.TryGetValue(cacheKey, out cacheValue))
            {
                try
                {
                    ((Func <IDataRecord, T>)cacheValue.Loader).Invoke(reader);
                    return(true);
                }
                // safe:
                //   The exception is intercepted here only once in order to generate new loader code.
                //   (Very unlikely to happen.)
                catch
                {
                    Cache.Loaders.TryRemove(cacheKey, out cacheValue);
                    return(false);
                }
            }

            return(false);
        }
示例#2
0
        internal static Func <IDataRecord, T> ProvideLoader <T>(IDataRecord reader, out QueryTalkException exception)
        {
            exception = null;
            object loader;
            Type   type = typeof(T);

            Loader.ColumnInfo[]    columns;
            Cache.LoaderCacheKey   cacheKey = Cache.LoaderCacheKey.Default;
            Cache.LoaderCacheValue cacheValue;
            var loaderType = Cache.GetLoaderType(type);
            int hash       = 0;

            // check cache
            if (Admin.IsLoaderCachingOn)
            {
                hash     = GetLoaderHash(reader);
                cacheKey = new Cache.LoaderCacheKey(hash, loaderType, type);
                if (Cache.TryGetLoaderCache <T>(reader, cacheKey, out cacheValue))
                {
                    return((Func <IDataRecord, T>)cacheValue.Loader);
                }
            }

            // dynamic loading
            if (loaderType == Cache.LoaderType.Dynamic)
            {
                columns = ReflectReader(reader, out exception);
                if (exception != null)
                {
                    exception.Arguments += String.Format("{0}   table = {1}", Environment.NewLine, type);
                    return(null);
                }

                TryThrowInvalidDataClassException(null, columns);

                Type dynamicType = Loader.EmitTable(columns, Guid.NewGuid());
                loader = Loader.EmitRowLoaderDynamic(columns, dynamicType);
            }
            // Row
            else if (loaderType == Cache.LoaderType.Row)
            {
                columns = ReflectRow(type, reader);
                TryThrowInvalidDataClassException(type, columns);
                loader = Loader.EmitRowLoader <T>(columns);
            }
            // regular data class
            else
            {
                columns = ReflectClass(type, reader);
                TryThrowInvalidDataClassException(type, columns);
                loader = Loader.EmitRowLoader <T>(columns);
            }

            // cache loader
            if (Admin.IsLoaderCachingOn)
            {
                cacheValue = new Cache.LoaderCacheValue(columns, loader);
                Cache.Loaders.TryAdd(cacheKey, cacheValue);
            }

            return((Func <IDataRecord, T>)loader);
        }