ObjectDisposedException в классе подключения к базе данных c # - PullRequest
0 голосов
/ 26 апреля 2018

Я новичок в C #, я программирую приложение на C #, которое требует подключения базы данных sqlite.Я подумал, что мне будет проще создать свой собственный класс DBConnection, который я дал ниже.Основная проблема, с которой я столкнулся на данный момент, связана с деструктором.Иногда, когда я создаю экземпляр этого класса и он выходит из области видимости, я получаю

System.ObjectDisposedException;«Невозможно получить доступ к удаленному объекту.Имя объекта: 'SQLiteConnection'. '

Теперь я искал определение того, что это значит, но я не совсем понимаю.

Объект создается как часть окна приложения wpf, и это исключение выдается после того, как окно будет удалено и после завершения операций с базой данных.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Data.SQLite;
using System.IO;

namespace PhotoSuppliesInc
{
    //this class will be used for connecting to the database in the various forms
    public class DBConnector
    {
        //----------------------------------PRIVATES------------------------------//
        //this is the connection to the db
        private SQLiteConnection dbConnection;

        //-------------------CONSTRUCTOR(S) and DESCTRUCTOR----------------//
        public DBConnector()
        {
                string connectionString = "Data Source=C:\\Users\\dmand\\source\\repos\\PhotoSuppliesInc\\PhotoSuppliesInc\\database\\riverfrontphoto.db;" +
                                            "Version = 3; FailIfMissing=True; Foreign Keys=True;";
                try
                {
                    dbConnection = new SQLiteConnection(connectionString);
                    dbConnection.Open();
                    MessageBox.Show("Database connected successfully");
                }//end try
                catch (SQLiteException e) { MessageBox.Show("error opening database"); }
        }//end constructor
        //destructor removes connection to database
        ~DBConnector()
        {
                dbConnection.Close();
        }
        //--------------------------------------------------GETTER(S)------------------------//
        //public string Get_Filepath() { return filepath; }

        //--------------------------------------------------UTILITY FUNCTIONS----------------//
        public List<string> Select_Query(string query_string, string columns)
        {
            //the names of the columns in the select statement
            string[] selection_columns = columns.Split();
            //each member of the array is the tuple, the data is separated by spaces
            List<string> result = new List<string>();
            //this string constructs the result line to be inserted into the result list
            string tempstring;
            SQLiteCommand command = new SQLiteCommand(query_string, dbConnection);
            SQLiteDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                tempstring = "";//reset the temp string for each tuple
                int i = 0;
                foreach(string s in selection_columns)
                {
                    tempstring += reader[s] + " ";
                    i++;
                }
                //I'm not sure why result.add must go here, but it does
                result.Add(tempstring);
            }
            //the result is a list who's contents are strings that represent each tuple
            return result;
        }
    }//end class
}//end namespace

///////in LoginWindow.xaml.cs////

Этокак я использую класс в файле кода окна....

 public LoginWindow()
        {
            InitializeComponent();

            //testing the DBConnector class:
            DBConnector riverfront = new DBConnector();
            string output_string = "";
            foreach (string s in riverfront.Select_Query(@"select distinct fname || ' ' || lname as 'Full_Name', country from employee, employee_account limit 5", "Full_Name country"))
                output_string += s + "\n";
            MessageBox.Show(output_string);
        }

...

Как я уже сказал, я не знаю, что означает эта ошибка, или правильно ли я использую деструктор в этом языке.Мне кажется, здесь не должно быть проблем.Может ли кто-нибудь помочь мне понять, что означает эта ошибка в моем классе?Спасибо всем за ваше время.

1 Ответ

0 голосов
/ 26 апреля 2018

Вы не правильно используете "деструкторы", потому что в C # нет деструкторов , у него есть финализаторы .

Правильный способ сделать то, что вы пытаетесь сделать, - реализовать шаблон IDisposable и обращаться к экземплярам вашего класса в пределах блоков using.

Финализаторы (обозначается синтаксисом ~) недетерминированы - вы не можете контролировать, когда сборщик мусора запускает финализатор или вообще когда-либо.Реализация IDisposable и доступ к экземплярам в блоке using позволяет вам реализовать детерминированную очистку ресурсов.

Вот почему вы получаете ObjectDisposedException: финализатор вашего класса работает после Ваш экземпляр SQLiteConnection утилизирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...