ViewPage IDataController.GetPage(string controller, string view, PageRequest request)
        {
            SelectView(controller, view);
            request.AssignContext(controller, this._viewId);
            ViewPage page = new ViewPage(request);

            if (_config.PlugIn != null)
            {
                _config.PlugIn.PreProcessPageRequest(request, page);
            }
            _config.AssignDynamicExpressions(page);
            page.ApplyDataFilter(_config.CreateDataFilter(), request.Controller, request.View, request.LookupContextController, request.LookupContextView, request.LookupContextFieldName);
            BusinessRules rules = _config.CreateBusinessRules();

            _serverRules = rules;
            if (_serverRules == null)
            {
                _serverRules = CreateBusinessRules();
            }
            _serverRules.Page             = page;
            _serverRules.RequiresRowCount = (page.RequiresRowCount && !((request.Inserting || request.DoesNotRequireData)));
            if (rules != null)
            {
                rules.BeforeSelect(request);
            }
            else
            {
                _serverRules.ExecuteServerRules(request, ActionPhase.Before);
            }
            using (DbConnection connection = CreateConnection())
            {
                if (_serverRules.RequiresRowCount)
                {
                    DbCommand countCommand = CreateCommand(connection);
                    ConfigureCommand(countCommand, page, CommandConfigurationType.SelectCount, null);
                    if (YieldsSingleRow(countCommand))
                    {
                        page.TotalRowCount = 1;
                    }
                    else
                    {
                        page.TotalRowCount = Convert.ToInt32(countCommand.ExecuteScalar());
                    }
                    if (page.RequiresAggregates)
                    {
                        DbCommand aggregateCommand = CreateCommand(connection);
                        ConfigureCommand(aggregateCommand, page, CommandConfigurationType.SelectAggregates, null);
                        DbDataReader reader = aggregateCommand.ExecuteReader();
                        if (reader.Read())
                        {
                            object[] aggregates = new object[page.Fields.Count];
                            for (int i = 0; (i < aggregates.Length); i++)
                            {
                                DataField field = page.Fields[i];
                                if (field.Aggregate != DataFieldAggregate.None)
                                {
                                    object v = reader[field.Name];
                                    if (!(DBNull.Value.Equals(v)))
                                    {
                                        if (!(field.FormatOnClient) && !(String.IsNullOrEmpty(field.DataFormatString)))
                                        {
                                            v = String.Format(field.DataFormatString, v);
                                        }
                                        aggregates[i] = v;
                                    }
                                }
                            }
                            page.Aggregates = aggregates;
                        }
                        reader.Close();
                    }
                }
                if (page.RequiresMetaData)
                {
                    PopulatePageCategories(page);
                }
                SyncRequestedPage(request, page, connection);
                DbCommand selectCommand = CreateCommand(connection);
                ConfigureCommand(selectCommand, page, CommandConfigurationType.Select, null);
                if ((page.PageSize > 0) && !((request.Inserting || request.DoesNotRequireData)))
                {
                    EnsureSystemPageFields(request, page, selectCommand);
                    DbDataReader reader = null;
                    if (selectCommand == null)
                    {
                        reader = ExecuteVirtualReader(request, page);
                    }
                    else
                    {
                        reader = TransactionManager.ExecuteReader(request, page, selectCommand);
                    }
                    while (page.SkipNext())
                    {
                        reader.Read();
                    }
                    while (page.ReadNext() && reader.Read())
                    {
                        object[] values = new object[page.Fields.Count];
                        for (int i = 0; (i < values.Length); i++)
                        {
                            DataField field = page.Fields[i];
                            object    v     = reader[field.Name];
                            if (!(DBNull.Value.Equals(v)))
                            {
                                if (field.IsMirror)
                                {
                                    v = String.Format(field.DataFormatString, v);
                                }
                                else
                                if ((field.Type == "Guid") && (v.GetType() == typeof(byte[])))
                                {
                                    v = new Guid(((byte[])(v)));
                                }
                                else
                                {
                                    v = ConvertObjectToValue(v);
                                }
                                values[i] = v;
                            }
                            if (!(String.IsNullOrEmpty(field.SourceFields)))
                            {
                                values[i] = CreateValueFromSourceFields(field, reader);
                            }
                        }
                        page.Rows.Add(values);
                    }
                    reader.Close();
                }
            }
            if (_config.PlugIn != null)
            {
                _config.PlugIn.ProcessPageRequest(request, page);
            }
            if (request.Inserting)
            {
                page.NewRow = new object[page.Fields.Count];
            }
            if (request.Inserting)
            {
                if (_serverRules.SupportsCommand("Sql|Code", "New"))
                {
                    _serverRules.ExecuteServerRules(request, ActionPhase.Execute, "New", page.NewRow);
                }
            }
            else
            if (_serverRules.SupportsCommand("Sql|Code", "Select"))
            {
                foreach (object[] row in page.Rows)
                {
                    _serverRules.ExecuteServerRules(request, ActionPhase.Execute, "Select", row);
                }
            }
            if (rules != null)
            {
                IRowHandler rowHandler = rules;
                if (request.Inserting)
                {
                    if (rowHandler.SupportsNewRow(request))
                    {
                        rowHandler.NewRow(request, page, page.NewRow);
                    }
                }
                else
                if (rowHandler.SupportsPrepareRow(request))
                {
                    foreach (object[] row in page.Rows)
                    {
                        rowHandler.PrepareRow(request, page, row);
                    }
                }
                if (rules != null)
                {
                    rules.ProcessPageRequest(request, page);
                }
            }
            page = page.ToResult(_config, _view);
            if (rules != null)
            {
                rules.AfterSelect(request);
            }
            else
            {
                _serverRules.ExecuteServerRules(request, ActionPhase.After);
            }
            _serverRules.Result.Merge(page);
            return(page);
        }