// <fileinfo name="Northwind_Base.cs">
//      <copyright>
//          All rights reserved.
//      </copyright>
//      <remarks>
//          Do not change this source code manually. Changes to this file may 
//          cause incorrect behavior and will be lost if the code is regenerated.
//      </remarks>
//      <generator rewritefile="True" infourl="http://www.SharpPower.com">RapTier</generator>
// </fileinfo>

using System;
using System.Data;

namespace MyCompany.MyProject.Db
{
    /// <summary>
    /// The base class for the <see cref="Northwind"/> class that 
    /// represents a connection to the <c>Northwind</c> database. 
    /// </summary>
    /// <remarks>
    /// Do not change this source code. Modify the Northwind class
    /// if you need to add or change some functionality.
    /// </remarks>
    public abstract class Northwind_Base : IDisposable
    {
        private IDbConnection _connection;
        private IDbTransaction _transaction;
        private StoredProcedures _storedProcedures;

        // Table and view fields
        private AlphabeticallistofproductsCollection _alphabeticallistofproducts;
        private CategoriesCollection _categories;
        private CategorySalesfor1997Collection _categorySalesfor1997;
        private CurrentProductListCollection _currentProductList;
        private CustomerandSuppliersbyCityCollection _customerandSuppliersbyCity;
        private CustomerCustomerDemoCollection _customerCustomerDemo;
        private CustomerDemographicsCollection _customerDemographics;
        private CustomersCollection _customers;
        private EmployeesCollection _employees;
        private EmployeeTerritoriesCollection _employeeTerritories;
        private InvoicesCollection _invoices;
        private OrderDetailsCollection _orderDetails;
        private OrderDetailsExtendedCollection _orderDetailsExtended;
        private OrderSubtotalsCollection _orderSubtotals;
        private OrdersCollection _orders;
        private OrdersQryCollection _ordersQry;
        private ProductSalesfor1997Collection _productSalesfor1997;
        private ProductsCollection _products;
        private ProductsAboveAveragePriceCollection _productsAboveAveragePrice;
        private ProductsbyCategoryCollection _productsbyCategory;
        private QuarterlyOrdersCollection _quarterlyOrders;
        private RegionCollection _region;
        private SalesbyCategoryCollection _salesbyCategory;
        private SalesTotalsbyAmountCollection _salesTotalsbyAmount;
        private ShippersCollection _shippers;
        private SummaryofSalesbyQuarterCollection _summaryofSalesbyQuarter;
        private SummaryofSalesbyYearCollection _summaryofSalesbyYear;
        private SuppliersCollection _suppliers;
        private TerritoriesCollection _territories;

        /// <summary>
        /// Initializes a new instance of the <see cref="Northwind_Base"/> 
        /// class and opens the database connection.
        /// </summary>
        protected Northwind_Base() : this(true)
        {
            // EMPTY
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Northwind_Base"/> class.
        /// </summary>
        /// <param name="init">Specifies whether the constructor calls the
        /// <see cref="InitConnection"/> method to initialize the database connection.</param>
        protected Northwind_Base(bool init)
        {
            if(init)
                InitConnection();
        }

        /// <summary>
        /// Initializes the database connection.
        /// </summary>
        protected void InitConnection()
        {
            _connection = CreateConnection();
            _connection.Open();
        }

        /// <summary>
        /// Creates a new connection to the database.
        /// </summary>
        /// <returns>A reference to the <see cref="System.Data.IDbConnection"/> object.</returns>
        protected abstract IDbConnection CreateConnection();

        /// <summary>
        /// Returns a SQL statement parameter name that is specific for the data provider.
        /// For example it returns ? for OleDb provider, or @paramName for MS SQL provider.
        /// </summary>
        /// <param name="paramName">The data provider neutral SQL parameter name.</param>
        /// <returns>The SQL statement parameter name.</returns>
        protected internal abstract string CreateSqlParameterName(string paramName);

        /// <summary>
        /// Creates <see cref="System.Data.IDataReader"/> for the specified DB command.
        /// </summary>
        /// <param name="command">The <see cref="System.Data.IDbCommand"/> object.</param>
        /// <returns>A reference to the <see cref="System.Data.IDataReader"/> object.</returns>
        protected internal virtual IDataReader ExecuteReader(IDbCommand command)
        {
            return command.ExecuteReader();
        }

        /// <summary>
        /// Adds a new parameter to the specified command. It is not recommended that 
        /// you use this method directly from your custom code. Instead use the 
        /// <c>AddParameter</c> method of the <TableCodeName>Collection_Base classes.
        /// </summary>
        /// <param name="cmd">The <see cref="System.Data.IDbCommand"/> object to add the parameter to.</param>
        /// <param name="paramName">The name of the parameter.</param>
        /// <param name="dbType">One of the <see cref="System.Data.DbType"/> values. </param>
        /// <param name="value">The value of the parameter.</param>
        /// <returns>A reference to the added parameter.</returns>
        internal IDbDataParameter AddParameter(IDbCommand cmd, string paramName,
                                                DbType dbType, object value)
        {
            IDbDataParameter parameter = cmd.CreateParameter();
            parameter.ParameterName = CreateCollectionParameterName(paramName);
            parameter.DbType = dbType;
            parameter.Value = null == value ? DBNull.Value : value;
            cmd.Parameters.Add(parameter);
            return parameter;
        }
        
        /// <summary>
        /// Creates a .Net data provider specific name that is used by the 
        /// <see cref="AddParameter"/> method.
        /// </summary>
        /// <param name="baseParamName">The base name of the parameter.</param>
        /// <returns>The full data provider specific parameter name.</returns>
        protected abstract string CreateCollectionParameterName(string baseParamName);

        /// <summary>
        /// Gets <see cref="System.Data.IDbConnection"/> associated with this object.
        /// </summary>
        /// <value>A reference to the <see cref="System.Data.IDbConnection"/> object.</value>
        public IDbConnection Connection
        {
            get { return _connection; }
        }

        /// <summary>
        /// Gets an object that represents the <c>Alphabetical list of products</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="AlphabeticallistofproductsCollection"/> object.</value>
        public AlphabeticallistofproductsCollection AlphabeticallistofproductsCollection
        {
            get
            {
                if(null == _alphabeticallistofproducts)
                    _alphabeticallistofproducts = new AlphabeticallistofproductsCollection((Northwind)this);
                return _alphabeticallistofproducts;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Categories</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="CategoriesCollection"/> object.</value>
        public CategoriesCollection CategoriesCollection
        {
            get
            {
                if(null == _categories)
                    _categories = new CategoriesCollection((Northwind)this);
                return _categories;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Category Sales for 1997</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="CategorySalesfor1997Collection"/> object.</value>
        public CategorySalesfor1997Collection CategorySalesfor1997Collection
        {
            get
            {
                if(null == _categorySalesfor1997)
                    _categorySalesfor1997 = new CategorySalesfor1997Collection((Northwind)this);
                return _categorySalesfor1997;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Current Product List</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="CurrentProductListCollection"/> object.</value>
        public CurrentProductListCollection CurrentProductListCollection
        {
            get
            {
                if(null == _currentProductList)
                    _currentProductList = new CurrentProductListCollection((Northwind)this);
                return _currentProductList;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Customer and Suppliers by City</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="CustomerandSuppliersbyCityCollection"/> object.</value>
        public CustomerandSuppliersbyCityCollection CustomerandSuppliersbyCityCollection
        {
            get
            {
                if(null == _customerandSuppliersbyCity)
                    _customerandSuppliersbyCity = new CustomerandSuppliersbyCityCollection((Northwind)this);
                return _customerandSuppliersbyCity;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>CustomerCustomerDemo</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="CustomerCustomerDemoCollection"/> object.</value>
        public CustomerCustomerDemoCollection CustomerCustomerDemoCollection
        {
            get
            {
                if(null == _customerCustomerDemo)
                    _customerCustomerDemo = new CustomerCustomerDemoCollection((Northwind)this);
                return _customerCustomerDemo;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>CustomerDemographics</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="CustomerDemographicsCollection"/> object.</value>
        public CustomerDemographicsCollection CustomerDemographicsCollection
        {
            get
            {
                if(null == _customerDemographics)
                    _customerDemographics = new CustomerDemographicsCollection((Northwind)this);
                return _customerDemographics;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Customers</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="CustomersCollection"/> object.</value>
        public CustomersCollection CustomersCollection
        {
            get
            {
                if(null == _customers)
                    _customers = new CustomersCollection((Northwind)this);
                return _customers;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Employees</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="EmployeesCollection"/> object.</value>
        public EmployeesCollection EmployeesCollection
        {
            get
            {
                if(null == _employees)
                    _employees = new EmployeesCollection((Northwind)this);
                return _employees;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>EmployeeTerritories</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="EmployeeTerritoriesCollection"/> object.</value>
        public EmployeeTerritoriesCollection EmployeeTerritoriesCollection
        {
            get
            {
                if(null == _employeeTerritories)
                    _employeeTerritories = new EmployeeTerritoriesCollection((Northwind)this);
                return _employeeTerritories;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Invoices</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="InvoicesCollection"/> object.</value>
        public InvoicesCollection InvoicesCollection
        {
            get
            {
                if(null == _invoices)
                    _invoices = new InvoicesCollection((Northwind)this);
                return _invoices;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Order Details</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="OrderDetailsCollection"/> object.</value>
        public OrderDetailsCollection OrderDetailsCollection
        {
            get
            {
                if(null == _orderDetails)
                    _orderDetails = new OrderDetailsCollection((Northwind)this);
                return _orderDetails;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Order Details Extended</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="OrderDetailsExtendedCollection"/> object.</value>
        public OrderDetailsExtendedCollection OrderDetailsExtendedCollection
        {
            get
            {
                if(null == _orderDetailsExtended)
                    _orderDetailsExtended = new OrderDetailsExtendedCollection((Northwind)this);
                return _orderDetailsExtended;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Order Subtotals</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="OrderSubtotalsCollection"/> object.</value>
        public OrderSubtotalsCollection OrderSubtotalsCollection
        {
            get
            {
                if(null == _orderSubtotals)
                    _orderSubtotals = new OrderSubtotalsCollection((Northwind)this);
                return _orderSubtotals;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Orders</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="OrdersCollection"/> object.</value>
        public OrdersCollection OrdersCollection
        {
            get
            {
                if(null == _orders)
                    _orders = new OrdersCollection((Northwind)this);
                return _orders;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Orders Qry</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="OrdersQryCollection"/> object.</value>
        public OrdersQryCollection OrdersQryCollection
        {
            get
            {
                if(null == _ordersQry)
                    _ordersQry = new OrdersQryCollection((Northwind)this);
                return _ordersQry;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Product Sales for 1997</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="ProductSalesfor1997Collection"/> object.</value>
        public ProductSalesfor1997Collection ProductSalesfor1997Collection
        {
            get
            {
                if(null == _productSalesfor1997)
                    _productSalesfor1997 = new ProductSalesfor1997Collection((Northwind)this);
                return _productSalesfor1997;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Products</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="ProductsCollection"/> object.</value>
        public ProductsCollection ProductsCollection
        {
            get
            {
                if(null == _products)
                    _products = new ProductsCollection((Northwind)this);
                return _products;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Products Above Average Price</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="ProductsAboveAveragePriceCollection"/> object.</value>
        public ProductsAboveAveragePriceCollection ProductsAboveAveragePriceCollection
        {
            get
            {
                if(null == _productsAboveAveragePrice)
                    _productsAboveAveragePrice = new ProductsAboveAveragePriceCollection((Northwind)this);
                return _productsAboveAveragePrice;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Products by Category</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="ProductsbyCategoryCollection"/> object.</value>
        public ProductsbyCategoryCollection ProductsbyCategoryCollection
        {
            get
            {
                if(null == _productsbyCategory)
                    _productsbyCategory = new ProductsbyCategoryCollection((Northwind)this);
                return _productsbyCategory;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Quarterly Orders</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="QuarterlyOrdersCollection"/> object.</value>
        public QuarterlyOrdersCollection QuarterlyOrdersCollection
        {
            get
            {
                if(null == _quarterlyOrders)
                    _quarterlyOrders = new QuarterlyOrdersCollection((Northwind)this);
                return _quarterlyOrders;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Region</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="RegionCollection"/> object.</value>
        public RegionCollection RegionCollection
        {
            get
            {
                if(null == _region)
                    _region = new RegionCollection((Northwind)this);
                return _region;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Sales by Category</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="SalesbyCategoryCollection"/> object.</value>
        public SalesbyCategoryCollection SalesbyCategoryCollection
        {
            get
            {
                if(null == _salesbyCategory)
                    _salesbyCategory = new SalesbyCategoryCollection((Northwind)this);
                return _salesbyCategory;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Sales Totals by Amount</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="SalesTotalsbyAmountCollection"/> object.</value>
        public SalesTotalsbyAmountCollection SalesTotalsbyAmountCollection
        {
            get
            {
                if(null == _salesTotalsbyAmount)
                    _salesTotalsbyAmount = new SalesTotalsbyAmountCollection((Northwind)this);
                return _salesTotalsbyAmount;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Shippers</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="ShippersCollection"/> object.</value>
        public ShippersCollection ShippersCollection
        {
            get
            {
                if(null == _shippers)
                    _shippers = new ShippersCollection((Northwind)this);
                return _shippers;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Summary of Sales by Quarter</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="SummaryofSalesbyQuarterCollection"/> object.</value>
        public SummaryofSalesbyQuarterCollection SummaryofSalesbyQuarterCollection
        {
            get
            {
                if(null == _summaryofSalesbyQuarter)
                    _summaryofSalesbyQuarter = new SummaryofSalesbyQuarterCollection((Northwind)this);
                return _summaryofSalesbyQuarter;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Summary of Sales by Year</c> view.
        /// </summary>
        /// <value>A reference to the <see cref="SummaryofSalesbyYearCollection"/> object.</value>
        public SummaryofSalesbyYearCollection SummaryofSalesbyYearCollection
        {
            get
            {
                if(null == _summaryofSalesbyYear)
                    _summaryofSalesbyYear = new SummaryofSalesbyYearCollection((Northwind)this);
                return _summaryofSalesbyYear;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Suppliers</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="SuppliersCollection"/> object.</value>
        public SuppliersCollection SuppliersCollection
        {
            get
            {
                if(null == _suppliers)
                    _suppliers = new SuppliersCollection((Northwind)this);
                return _suppliers;
            }
        }

        /// <summary>
        /// Gets an object that represents the <c>Territories</c> table.
        /// </summary>
        /// <value>A reference to the <see cref="TerritoriesCollection"/> object.</value>
        public TerritoriesCollection TerritoriesCollection
        {
            get
            {
                if(null == _territories)
                    _territories = new TerritoriesCollection((Northwind)this);
                return _territories;
            }
        }

        /// <summary>
        /// Gets an object that wraps the database stored procedures.
        /// </summary>
        /// <value>A reference to the <see cref="StoredProcedures"/> object.</value>
        public StoredProcedures StoredProcedures
        {
            get
            {
                if(null == _storedProcedures)
                    _storedProcedures = new StoredProcedures((Northwind)this);
                return _storedProcedures;
            }
        }

        /// <summary>
        /// Begins a new database transaction.
        /// </summary>
        /// <seealso cref="CommitTransaction"/>
        /// <seealso cref="RollbackTransaction"/>
        /// <returns>An object representing the new transaction.</returns>
        public IDbTransaction BeginTransaction()
        {
            CheckTransactionState(false);
            _transaction = _connection.BeginTransaction();
            return _transaction;
        }

        /// <summary>
        /// Begins a new database transaction with the specified 
        /// transaction isolation level.
        /// <seealso cref="CommitTransaction"/>
        /// <seealso cref="RollbackTransaction"/>
        /// </summary>
        /// <param name="isolationLevel">The transaction isolation level.</param>
        /// <returns>An object representing the new transaction.</returns>
        public IDbTransaction BeginTransaction(IsolationLevel isolationLevel)
        {
            CheckTransactionState(false);
            _transaction = _connection.BeginTransaction(isolationLevel);
            return _transaction;
        }

        /// <summary>
        /// Commits the current database transaction.
        /// <seealso cref="BeginTransaction"/>
        /// <seealso cref="RollbackTransaction"/>
        /// </summary>
        public void CommitTransaction()
        {
            CheckTransactionState(true);
            _transaction.Commit();
            _transaction = null;
        }

        /// <summary>
        /// Rolls back the current transaction from a pending state.
        /// <seealso cref="BeginTransaction"/>
        /// <seealso cref="CommitTransaction"/>
        /// </summary>
        public void RollbackTransaction()
        {
            CheckTransactionState(true);
            _transaction.Rollback();
            _transaction = null;
        }

        // Checks the state of the current transaction
        private void CheckTransactionState(bool mustBeOpen)
        {
            if(mustBeOpen)
            {
                if(null == _transaction)
                    throw new InvalidOperationException("Transaction is not open.");
            }
            else
            {
                if(null != _transaction)
                    throw new InvalidOperationException("Transaction is already open.");
            }
        }

        /// <summary>
        /// Creates and returns a new <see cref="System.Data.IDbCommand"/> object.
        /// </summary>
        /// <param name="sqlText">The text of the query.</param>
        /// <returns>An <see cref="System.Data.IDbCommand"/> object.</returns>
        internal IDbCommand CreateCommand(string sqlText)
        {
            return CreateCommand(sqlText, false);
        }

        /// <summary>
        /// Creates and returns a new <see cref="System.Data.IDbCommand"/> object.
        /// </summary>
        /// <param name="sqlText">The text of the query.</param>
        /// <param name="procedure">Specifies whether the sqlText parameter is 
        /// the name of a stored procedure.</param>
        /// <returns>An <see cref="System.Data.IDbCommand"/> object.</returns>
        internal IDbCommand CreateCommand(string sqlText, bool procedure)
        {
            IDbCommand cmd = _connection.CreateCommand();
            cmd.CommandText = sqlText;
            cmd.Transaction = _transaction;
            if(procedure)
                cmd.CommandType = CommandType.StoredProcedure;
            return cmd;
        }

        /// <summary>
        /// Rolls back any pending transactions and closes the DB connection.
        /// An application can call the <c>Close</c> method more than
        /// one time without generating an exception.
        /// </summary>
        public virtual void Close()
        {
            if(null != _connection)
                _connection.Close();
        }

        /// <summary>
        /// Rolls back any pending transactions and closes the DB connection.
        /// </summary>
        public virtual void Dispose()
        {
            Close();
            if(null != _connection)
                _connection.Dispose();
        }
    } // End of Northwind_Base class
} // End of namespace