2011-10-19 7 views
1

私は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; 
     } 
    } 
} 

私はプログラムが開いたときに​​を置くことdbコンストラクタを呼ぶだろうと思ったが、ときコードがdataReader = query.ExecuteReader();行になると、 "ExecuteReader:Connectionプロパティが初期化されていません"というエラーが表示されます。

私が達成しようとしているすべては私が電話し、私のコードの全てに利用できる持っていることを、別のクラス内のデータベース接続です。

私は別の方法でデータベースクラスを呼び出すと思いますか?

+0

アプリケーションを起動するクラスが必要です。この場合、プログラムであることを考慮すると、別のクラスを継承することはできません。作成したクラスを継承する理由はありません。 –

+0

あなたのアドバイスのおかげで、私はそれを持ってそれから学ぶでしょう! – Luke

答えて

13

いいえ、何もProgramのインスタンスを作成していないですし、何もdbのインスタンスを作成していないです。データベース接続のための静的フィールドをお持ちでない

  • を:しかし、私はを強くは、あなたが完全にあなたのデザインを変更することをお勧めしたいです。必要なときにそれを開き、それを使用して閉じます。非常にまれに、ローカル変数以外に格納する必要はありません。
  • 静的変数を使用しないでください。彼らはあなたのコードをグローバルな状態を表すので、テストするのが難しくなります - それは地方の状態よりも推論するのが難しくなります。あなたのプログラムでは、私はローカル変数を完全に使います。
  • この種のものの継承を使用しないでください - あなたのProgramタイプは、論理的には、メソッド、クラスやプロパティのdb
  • フォロー.NETの命名規則から派生しませありません。慣用的なC#のようなあなたのコードを "気持ち"にすることは、他の人に読めるようにするための長い道のりになります。
6

これは正しく表示されません。プログラムはデータベースクラスを継承したり拡張したりしないでください。あなたのデータベースクラスはそれ自身の抽象データ型です。あなたのプログラムはデータベースクラスを使用するべきですが、それを拡張しないでください。

私はあなたのプログラムは、その後できるデータベースクラスに静的クラス(ここでは、データベース・インスタンスをインスタンス化する理由はない)

  • を作る継承
  • 退治

    1. によって少しこれを変更します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クラスのオブジェクトを非表示にします。 MyDBClassの書き込み/データベースの読み取りを管理静的なクラスです

    MyDBClass.GetHousesFromDB()

    :あなたのgetHousesFromDBは次のように呼ばれるべきです。 GetHousesFromDBの署名は、IList<House> GetHousesFromDB()

  • 4

    の効果に何かを返すはずですが、Jon Skeet & JonHが有効な点を示していますが、なぜ例外が発生しているのかをお答えします。そこから助言を取り、これを最初からやり直すべきです。

    例外が発生する理由は、コンストラクタでdbのために初期化され、呼び出されないことです。

    この行をMainに追加すると、プログラムが機能するはずです。

    new Program(); 
    

    しかし、繰り返して:アドバイスを受け、やり直してください。多くの設定では、これらのおもちゃのプロジェクトは急速に成長し、エンタープライズアプリケーションに満ちています。そこに着くと、最初の間違いは永遠にそこにとどまります。

    +1

    +1これらのおもちゃのプロジェクトはすぐに私たちの組織全体を実行しているシステムのような完全なエンタープライズアプリケーションに成長する*一息* – JonH

    関連する問題