public IEnumerable Enumerable( string query, QueryParameters parameters ) { CheckIsOpen(); if( log.IsDebugEnabled ) { log.Debug( "GetEnumerable: " + query ); parameters.LogParameters( factory ); } QueryTranslator[ ] q = GetQueries( query, true ); if( q.Length == 0 ) { return new ArrayList(); } IEnumerable result = null; IEnumerable[ ] results = null; bool many = q.Length > 1; if( many ) { results = new IEnumerable[q.Length]; } dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called //execute the queries and return all results as a single enumerable try { for( int i = 0; i < q.Length; i++ ) { try { result = q[ i ].GetEnumerable( parameters, this ); } catch( HibernateException ) { // Do not call Convert on HibernateExceptions throw; } catch( Exception sqle ) { throw Convert( sqle, "Could not execute query" ); } if( many ) { results[ i ] = result; } } return many ? new JoinedEnumerable( results ) : result; } finally { dontFlushFromFind--; } }
/// <summary> /// 1. determine the collection role of the given collection (this may require a flush, if the collection is recorded as unreferenced) /// 2. obtain a compiled filter query /// 3. autoflush if necessary /// </summary> /// <param name="collection"></param> /// <param name="filter"></param> /// <param name="parameters"></param> /// <param name="scalar"></param> /// <returns></returns> private FilterTranslator GetFilterTranslator( object collection, string filter, QueryParameters parameters, bool scalar ) { if( collection == null ) { throw new ArgumentNullException( "collection", "null collection passed to Filter" ); } if( log.IsDebugEnabled ) { log.Debug( "filter: " + filter ); parameters.LogParameters( factory ); } CollectionEntry entry = GetCollectionEntryOrNull( collection ); ICollectionPersister roleBeforeFlush = ( entry == null ) ? null : entry.loadedPersister; FilterTranslator filterTranslator; if( roleBeforeFlush == null ) { // if it was previously unreferenced, we need // to flush in order to get its state into the // database to query Flush(); entry = GetCollectionEntryOrNull( collection ); ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.loadedPersister; if( roleAfterFlush == null ) { throw new QueryException( "the collection was unreferenced" ); } filterTranslator = factory.GetFilter( filter, roleAfterFlush.Role, scalar ); } else { // otherwise, we only need to flush if there are // in-memory changes to the queried tables filterTranslator = factory.GetFilter( filter, roleBeforeFlush.Role, scalar ); if( AutoFlushIfRequired( filterTranslator.QuerySpaces ) ) { // might need to run a different filter entirely after the flush // because the collection role may have changed entry = GetCollectionEntryOrNull( collection ); ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.loadedPersister; if( roleBeforeFlush != roleAfterFlush ) { if( roleAfterFlush == null ) { throw new QueryException( "The collection was dereferenced" ); } } filterTranslator = factory.GetFilter( filter, roleAfterFlush.Role, scalar ); } } parameters.PositionalParameterValues[ 0 ] = entry.loadedKey; parameters.PositionalParameterTypes[ 0 ] = entry.loadedPersister.KeyType; return filterTranslator; }
public IList Find( string query, QueryParameters parameters ) { CheckIsOpen(); if( log.IsDebugEnabled ) { log.Debug( "find: " + query ); parameters.LogParameters( factory ); } parameters.ValidateParameters(); QueryTranslator[ ] q = GetQueries( query, false ); IList results = new ArrayList(); dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called //execute the queries and return all result lists as a single list try { for( int i = 0; i < q.Length; i++ ) { IList currentResults; try { currentResults = q[ i ].List( this, parameters ); } catch( Exception e ) { throw new ADOException( "Could not execute query", e ); } for( int j = 0; j < results.Count; j++ ) { currentResults.Add( results[ j ] ); } results = currentResults; } } finally { dontFlushFromFind--; } return results; }