/// <summary>
        /// Converts query result rows into Row objects, and adds them to the collection.
        /// </summary>
        internal void AddRows(DatabaseQuery query, IEnumerable <object> rows)
        {
            if (query.Raw.OrderBy == null || query.Raw.OrderBy.Count == 0)
            {
                // We can access the enumerable in parallel, the order doesn't matter.
                Rows.AddRange(rows.AsParallel().Select(
                                  obj => CreateRowFromObservableCollection(obj)));

                return;
            }

            // Access the enumerable in a series, because the order matters.
            Rows.AddRange(rows.Select(obj => CreateRowFromObservableCollection(obj)));
        }
        /// <summary>
        /// Converts query result rows into Row objects, and then executes the callback
        /// with each row. This is intended to be used by code that wants to perform some
        /// other aggregation over the returned query rows, to avoid the double enumeration
        /// cost of converting to the Row format and then reading those back in a different
        /// loop. This should be more efficient in that case because the data retrieval is
        /// network bound, so we have CPU time to spare.
        /// </summary>
        internal void CallbackRows(DatabaseQuery query, IEnumerable <object> rows, Action <Row> callback)
        {
            if (query.Raw.OrderBy == null || query.Raw.OrderBy.Count == 0)
            {
                // We can fire callbacks in parallel, the order doesn't matter.
                rows.AsParallel().ForAll(obj => callback(CreateRowFromObservableCollection(obj)));
                return;
            }

            // Access the enumerable in a series, because the order matters.
            foreach (object raw in rows)
            {
                callback(CreateRowFromObservableCollection(raw));
            }
        }