/// <summary>Executes a query and directly fills given collection with objects build from retrieved data.</summary>
 /// <param name="conn">Connection provider.</param>
 /// <param name="destination">A collection to fill with objects built from data.</param>
 /// <param name="objectBuilder">Builds objects directly from retrieved data.</param>
 /// <remarks><para>The method uses provided converter to directly build specified object type from data contained in
 /// <see cref="IDataReader"/> objects, thus skipping the need to create intermediate data structures such as <see cref="DataTable"/>
 /// and <see cref="DataSet"/> objects. This can increase performance and reduce memory consumption when working with very
 /// large results sets.</para>
 /// <example><para>The following example demonstrates the fastest way to fetch and initialize entity collection:<code>
 /// EmployeesMeta employees = new EmployeesMeta();
 /// SelectStatement select = new SelectStatement(employees, employees.Columns);
 /// var allEmployees = new EntityCollection&lt;EmployeesEntity, EmployeesMeta&gt;();
 /// select.FillCollection(allEmployees, employees.NewEntityFiller());
 /// </code></para>
 /// <para>Besides entity collections, you can also fill any custom collections or data structures by implementing your own <see cref="IObjectFiller"/> objects.
 /// The following example demonstrates the fastest way to fetch all values used in a single column of a table using custom developed object filler:<code>
 /// //Fetch all values from OrderID column of Order Details table.
 /// public List&lt;int&gt; FillOrderIdCollection()
 /// {
 ///     OrderDetailsMeta details = new OrderDetailsMeta();
 ///     SelectStatement select = new SelectStatement(details, details.OrderID);
 ///     // Operation is slightly faster if we can estimate the number of items that the target collection will contain.
 ///     var allItems = new List&lt;int&gt;(2200);
 ///     select.FillCollection(allItems, new SingleFieldFiller());
 ///     return allItems;
 /// }
 ///
 /// //Fills collection with primitive types.
 /// public class SingleFieldFiller : IObjectFiller
 /// {
 ///     public void FillCollection(IDataReader openedDataReader, IList collection)
 ///     {
 ///         while (openedDataReader.Read())
 ///         {
 ///             object value = openedDataReader.GetValue(0);
 ///             collection.Add(value);
 ///         }
 ///     }
 /// }
 /// </code></para></example></remarks>
 public void FillCollection(IConnectionProvider conn, IList destination, IObjectFiller objectBuilder)
 {
     this.ConnectionProvider = conn;
     FillCollection(destination, objectBuilder);
 }
Beispiel #2
0
        /// <summary>Executes a query and converts data to specified objects.</summary>
        /// <param name="conn">Connection provider.</param>
        /// <param name="destination">A collection to fill with objects built from data.</param>
        /// <param name="objectBuilder">Builds objects directly from retrieved data.</param>
        /// <param name="cmdText">Command text.</param>
        /// <param name="parameters">Command parameters.</param>
        /// <param name="cmdType">Command type (stored procedure or text).</param>
        /// <param name="cmdTimeout">Set timeout for specified command.</param>
        /// <param name="useSequentalAccess">Uses CommandBehavior.SequentialAccess instead of CommandBehavior.SingleResult.</param>
        /// <remarks><para>The method uses provided converter to directly build specified object type from data contained in
        /// <see cref="IDataReader"/> objects, thus skipping the need to create intermediate data structures such as <see cref="DataTable"/>
        /// and <see cref="DataSet"/> objects. This can increase performance and reduce memory consumption when working with very
        /// large results sets.</para></remarks>
        internal static void ExecuteReader(IConnectionProvider conn, IList destination, IObjectFiller objectBuilder, string cmdText, DbParameterCollection parameters, CommandType cmdType, int cmdTimeout, bool useSequentalAccess)
        {
            IDbCommand cmd = CreateCommand(conn.DBMS, cmdText, parameters, cmdType, cmdTimeout);
            cmd.Connection = conn.Connection;

            bool connIsOpennedLocally = EnsureOpenConnection(conn);
            try
            {
                AssignExistingPendingTransactionToCommand(conn, cmd);

                CommandBehavior behaviour = CommandBehavior.SingleResult;
                if (useSequentalAccess)
                    behaviour = CommandBehavior.SequentialAccess;

                using (IDataReader reader = cmd.ExecuteReader(behaviour))
                {
                    objectBuilder.FillCollection(reader, destination);
                    PopulateOutputParameterValues(parameters, cmd);
                }
            }
            finally
            {
                CloseConnectionIfLocal(conn, connIsOpennedLocally);
                cmd.Dispose();
            }
        }
        /// <summary>Executes a query and directly fills given collection with objects build from retrieved data.</summary>
        /// <param name="destination">A collection to fill with objects built from data.</param>
        /// <param name="objectBuilder">Builds objects directly from retrieved data.</param>
        /// <param name="cmdTimeout">Sets timeout for collection fetching SQL command. Default is 30 seconds.</param>
        /// <remarks><para>The method uses provided converter to directly build specified object type from data contained in
        /// <see cref="IDataReader"/> objects, thus skipping the need to create intermediate data structures such as <see cref="DataTable"/>
        /// and <see cref="DataSet"/> objects. This can increase performance and reduce memory consumption when working with very
        /// large results sets.</para>
        /// <example><para>The following example demonstrates the fastest way to fetch and initialize entity collection:<code>
        /// EmployeesMeta employees = new EmployeesMeta();
        /// SelectStatement select = new SelectStatement(employees, employees.Columns);
        /// var allEmployees = new EntityCollection&lt;EmployeesEntity, EmployeesMeta&gt;();
        /// select.FillCollection(allEmployees, employees.NewEntityFiller());
        /// </code></para>
        /// <para>Besides entity collections, you can also fill any custom collections or data structures by implementing your own <see cref="IObjectFiller"/> objects.
        /// The following example demonstrates the fastest way to fetch all values used in a single column of a table using custom developed object filler:<code>
        /// //Fetch all values from OrderID column of Order Details table.
        /// public List&lt;int&gt; FillOrderIdCollection()
        /// {
        ///     OrderDetailsMeta details = new OrderDetailsMeta();
        ///     SelectStatement select = new SelectStatement(details, details.OrderID);
        ///     // Operation is slightly faster if we can estimate the number of items that the target collection will contain.
        ///     var allItems = new List&lt;int&gt;(2200);
        ///     select.FillCollection(allItems, new SingleFieldFiller());
        ///     return allItems;
        /// }
        ///
        /// //Fills collection with primitive types.
        /// public class SingleFieldFiller : IObjectFiller
        /// {
        ///     public void FillCollection(IDataReader openedDataReader, IList collection)
        ///     {
        ///         while (openedDataReader.Read())
        ///         {
        ///             object value = openedDataReader.GetValue(0);
        ///             collection.Add(value);
        ///         }
        ///     }
        /// }
        /// </code></para></example></remarks>
        public void FillCollection(IList destination, IObjectFiller objectBuilder, int cmdTimeout = 30)
        {
            bool blobAware = false;
            DbParameterCollection parameters = new DbParameterCollection();
            StringBuilder cmdText = new StringBuilder();
            Render(this.ConnectionProvider.DBMS, cmdText, parameters);

            string command = cmdText.ToString();
            this.LastExecutedCommandInfo = new CommandExecutionStatistics(command);

            if (objectBuilder is IBlobFiller)
                blobAware = true;

            DbUtil.ExecuteReader(this.ConnectionProvider, destination, objectBuilder, command, parameters, CommandType.Text, cmdTimeout, blobAware);
            this.LastExecutedCommandInfo.StopTime();
        }