簡體   English   中英

調用類進行數據庫連接

[英]Calling class to do database connection

我在用C#編程。 我正在嘗試創建一個類,該類在被調用時將創建與數據庫的連接。

我的數據庫連接類在這里:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;

namespace HouseServer
{

    class db
    {

        // Variable to hold the driver and location of database
        public static OleDbConnection dbConnection;

        // Database connection
        public db()
        {

            // Define the Access Database driver and the filename of the database
            dbConnection = new OleDbConnection("Provider=Microsoft.Ace.OLEDB.12.0; Persist Security Info = False; Data Source=Houses.accdb");

            // Open the connection
            dbConnection.Open();
        }
    }
}

主程序在這里:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;

namespace HouseServer
{
    class Program : db
    {

        // List for holding loaded houses
        static List<house> houses = new List<house>();

        // Variable to hold "command" which is the query to be executed
        private static OleDbCommand query;

        // Variable to hold the data reader to manipulate data from the database
        static OleDbDataReader dataReader;

        static void Main(string[] args)
        {
            // Get the houses in a list
            List<house> c = getHousesFromDb();

            foreach (house yay in c)
            {
                // Show each house's full address
                Console.WriteLine(yay.house_number + " " + yay.street);
                Console.WriteLine(yay.house_town);
                Console.WriteLine(yay.postcode);
            }

            // Readline to prevent window from closing
            Console.ReadLine();
        }

        // Function which loads all of the houses from the database
        private static List<house> getHousesFromDb()
        {

            // Define the query to be executed
            query = new OleDbCommand("SELECT * FROM houses", dbConnection);

            // Execute the query on the database and get the data
            dataReader = query.ExecuteReader();

            // Loop through each of the houses
            while (dataReader.Read())
            {
                // Create a new house object for temporarily storing house
                house house = new house();

                // Create the house that we've just loaded
                house.house_id = Convert.ToInt32(dataReader["house_id"]);
                house.house_number = Convert.ToInt32(dataReader["house_number"]);
                house.street = dataReader["house_street"].ToString();
                house.house_town = dataReader["house_town"].ToString();
                house.postcode = dataReader["house_postcode"].ToString();

                // Now add the house to the list of houses
                houses.Add(house);
            }

            // Return all of the houses in the database as a List<house>
            return houses;
        }
    }
}

我以為放在class Program : db會在程序打開時調用db構造函數,但是當代碼到達該行時dataReader = query.ExecuteReader(); ,出現錯誤“ ExecuteReader:連接屬性尚未初始化”。

我想要實現的只是在另一個類中的數據庫連接,我可以調用該數據庫連接並將其用於所有代碼。

我應該以其他方式調用數據庫類嗎?

不,什么都沒有創建Program實例,什么也沒有創建db實例。 但是,我強烈建議您完全更改設計:

  • 沒有用於數據庫連接的靜態字段。 需要時將其打開,使用並關閉。 您幾乎不需要將其存儲在除局部變量以外的任何其他內容中。
  • 如果有幫助,請盡量不要使用靜態變量。 它們使您的代碼更難以測試,因為它們代表全局狀態-比局部狀態更難推理。 在您的程序中,我將完全使用局部變量。
  • 不要對此類事情使用繼承-您的Program類型在邏輯上不是從db派生的
  • 對於方法,類和屬性,請遵循.NET命名約定。 使您的代碼像慣用的C#一樣“感覺”將大大提高其可讀性。

這肯定看起來不合適,您的程序不應繼承或擴展數據庫類。 您的數據庫類本身就是其自己的抽象數據類型。 您的程序應使用數據庫類,但不能擴展它。

我會稍微改變一下

  1. 擺脫繼承
  2. 使數據庫類成為靜態類(無需在此處實例化數據庫實例)
  3. 然后,您的程序可以使用DBClass.GetData();

那就是您的程序應該將數據庫類用作黑匣子,它絕對不應從該類繼承。 它應該在沒有詳細工作原理的情況下使用它。 在您的代碼中:

// List for holding loaded houses
static List<house> houses = new List<house>();

// Variable to hold "command" which is the query to be executed
private static OleDbCommand query;

// Variable to hold the data reader to manipulate data from the database
static OleDbDataReader dataReader;

static void Main(string[] args)
{
    // Get the houses in a list
    List<house> c = getHousesFromDb();

您應該隱藏OleDbCommand和OleDbDatareader對象的詳細信息,盡管並不需要在其他地方對其進行管理。 您的getHousesFromDB應該這樣稱呼:

MyDBClass.GetHousesFromDB()

其中MyDBClass是管理數據庫讀/寫的靜態類。 GetHousesFromDB的簽名應該返回一些東西,以達到IList<House> GetHousesFromDB()的效果。

盡管喬恩·斯凱特(Jon Skeet)和喬恩(JonH)提出了正確的觀點,但我會回答您為什么會得到例外的原因。 從那里開始,您應該聽取他們的建議,並從頭開始重做。

出現異常的原因是它是在db的構造函數中初始化的,並且永遠不會被調用。

如果將此行添加到Main ,則程序應該可以運行。

new Program();

但要重申: 聽取他們的建議,然后重新開始。 在許多情況下,這些玩具項目迅速發展為功能完善的企業應用程序,一旦您到達那里,一開始的錯誤就永遠存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM