调用类进行数据库连接

发布于 2024-12-10 23:32:59 字数 3332 浏览 0 评论 0原文

我正在用 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:连接属性尚未初始化。”。

我想要实现的只是另一个类中的数据库连接,我可以调用它并可用于我的所有代码。

我应该以不同的方式调用数据库类吗?

I'm programming in C#. I'm trying to make a class, that when called will create a connection to the database.

My database connection class is here:

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();
        }
    }
}

And the main program is here:

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

I thought that putting class Program : db would call the db constructor when the program opens, but when the code gets to the line dataReader = query.ExecuteReader();, it comes up with the error "ExecuteReader: Connection property has not been initialized.".

All I'm trying to achieve is a database connection within another class, that I can call and have available to all of my code.

Am I supposed to call the database class in a different way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲鸠 2024-12-17 23:32:59

不,没有任何东西创建 Program 的实例,也没有任何东西创建 db 的实例。但是,我强烈建议您完全改变您的设计:

  • 不要为数据库连接设置静态字段。当你需要的时候打开它,使用它,关闭它。除了局部变量之外,您很少需要将其存储在任何其他内容中。
  • 如果可以的话,尽量不要使用静态变量。它们使您的代码更难测试,因为它们代表全局状态 - 这比本地状态更难推理。在您的程序中,我将完全使用局部变量。
  • 不要对此类事情使用继承 - 您的 Program 类型逻辑上不是从 db 派生的。
  • 遵循 .NET 方法命名约定,类和属性。让您的代码“感觉”像惯用的 C# 将大大有助于使其对其他人更具可读性。

No, nothing's creating an instance of Program, and nothing's creating an instance of db. However, I'd strongly suggest you change your design completely:

  • Don't have a static field for your database connection. Open it when you need one, use it, close it. You should very rarely need to store it in anything other than a local variable.
  • Try not to use static variables at all if you can help it. They make your code harder to test, as they represent global state - that's harder to reason about than local state. In your program, I'd use local variables entirely.
  • Don't use inheritance for this sort of thing - your Program type doesn't logically derive from db
  • Follow .NET naming conventions for methods, classes and properties. Making your code "feel" like idiomatic C# will go a long way to making it more readable for other people.
指尖上的星空 2024-12-17 23:32:59

这看起来肯定不对,你的程序不应该继承或扩展你的数据库类。您的数据库类本身就是它自己的抽象数据类型。您的程序应该使用数据库类,但不扩展它。

来对此进行一些更改

  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效果的内容。 GetHousesFromDB()

This definately doesn't look right, your program should not inherit or extend your database class. Your database class is in its own right its own abstract data type. Your program should use the database class but not extend it.

I would change this up a bit by

  1. Getting rid of the inheritance
  2. Make the database class a static class (no reason to instantiate a database instance here)
  3. Your program can then DBClass.GetData();

That is your program should use the database class as a black box, it definately should not inherit from it. It should use it without having the details of how it works. In your code:

// 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();

You should hide the details of your OleDbCommand and OleDbDatareader objects, although its not required they could be managed elsewhere. Your getHousesFromDB should be called like:

MyDBClass.GetHousesFromDB()

Where MyDBClass is a static class that manages your database read / writes. The signature of GetHousesFromDB should return something to the effect of IList<House> GetHousesFromDB()

冷︶言冷语的世界 2024-12-17 23:32:59

虽然乔恩·斯基特和JonH 提出了有效的观点,我会回答你为什么会得到例外。从那里你应该听取他们的建议并从头开始重做。

出现异常的原因是它是在 db 的构造函数中初始化的,并且永远不会被调用。

如果将此行添加到 Main 中,您的程序应该可以运行。

new Program();

但需要重申的是:听取他们的建议并重新开始。在许多情况下,这些玩具项目很快就会发展成为成熟的企业应用程序,一旦到达那里,一开始犯的错误就会永远留在那里。

Though Jon Skeet & JonH make valid points, I'll answer why you're getting the exception. From there you should take their advice and redo this from scratch.

The reason you get the exception is that it is initialized in the constructor for db and it's never getting called.

If you add this line to Main, your program should work.

new Program();

But to reiterate: Take their advice and start over. In many settings, these toy projects quickly grow to full blown enterprise apps and once you get there, the mistakes made at the beginning stay there forever.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文