Esempio n. 1
0
        private static IEnumerable <T> internalQuery <T>(this IDbConnection conn, CommandDefinition command)
        {
            // 缓存
            var         parameter   = command.Parameters;
            Certificate certificate = new Certificate(command.CommandText, command.CommandType, conn, typeof(T), parameter?.GetType());
            CacheInfo   cacheInfo   = CacheInfo.GetCacheInfo(certificate, parameter);
            // 读取
            IDbCommand  cmd       = null;
            IDataReader reader    = null;
            var         wasClosed = conn.State == ConnectionState.Closed;

            try {
                cmd = command.SetupCommand(conn, cacheInfo.ParameterReader);
                if (wasClosed)
                {
                    conn.Open();
                }
                reader = ExecuteReaderWithFlagsFallback(cmd, wasClosed, CommandBehavior.SingleResult);
                if (cacheInfo.Deserializer == null)
                {
                    cacheInfo.Deserializer = BuildDeserializer <T>(reader);
                }
                while (reader.Read())
                {
                    var val = cacheInfo.Deserializer(reader);
                    yield return(GetValue <T>(val));
                }
            } finally {
                // dispose
                if (reader != null)
                {
                    if (!reader.IsClosed)
                    {
                        try {
                            cmd.Cancel();
                        } catch {
                        }
                    }
                    reader.Dispose();
                }
                if (wasClosed)
                {
                    conn.Close();
                }
                cmd?.Dispose();
            }

            IDataReader ExecuteReaderWithFlagsFallback(IDbCommand c, bool close, CommandBehavior behavior)
            {
                try {
                    return(c.ExecuteReader(GetBehavior(close, behavior)));
                } catch (ArgumentException ex) {
                    throw;
                }
            }

            CommandBehavior GetBehavior(bool close, CommandBehavior @default)
            {
                return(close ? (@default | CommandBehavior.CloseConnection) : @default);
            }
        }