Click here to Skip to main content
15,886,864 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello. I'm programmer-beginner and I try to convert SQLite database to set of tables (like in example). What do I wrong? My constructor does't create object with correct tables.
Code of my class:

public class bazaDVD
    {
        public Klient[] Klienci;
        public Film[] Filmy;
        public Egzemplarz[] Egzemplarze;
        public Wypozyczenie[] Wypozyczenia;

        
        public bazaDVD ()
        {
            DataTable tabelkaK = new DataTable();
            DataTable tabelkaF = new DataTable();
            DataTable tabelkaE = new DataTable();
            DataTable tabelkaW = new DataTable();
            SQLiteConnection connect = new SQLiteConnection("Data SOurce = baza_wypozyczalnia.s3db");
            SQLiteDataAdapter adapterK = new SQLiteDataAdapter ("SELECT * FROM Klienci",connect);
            SQLiteDataAdapter adapterF = new SQLiteDataAdapter ("SELECT * FROM Filmy", connect);
            SQLiteDataAdapter adapterE = new SQLiteDataAdapter ("SELECT * FROM Egzemplarze", connect);
            SQLiteDataAdapter adapterW = new SQLiteDataAdapter("SELECT * FROM Wypozyczenia", connect);
            adapterK.Fill(tabelkaK);
            adapterF.Fill(tabelkaF);
            adapterE.Fill(tabelkaE);
            adapterW.Fill(tabelkaW);
            this.Klienci = DataK_TabelaK(tabelkaK);
            this.Filmy = DataF_TabelaF(tabelkaF);
            this.Egzemplarze = DataE_TabelaE(tabelkaE);
            this.Wypozyczenia = DataW_TabelaW(tabelkaW);

        }
        

        private Klient[] DataK_TabelaK (DataTable tabelaK)
        {
            for (int i=0; i<tabelaK.Rows.Count; i++)
            {
                Klienci = new Klient[tabelaK.Rows.Count];
                Klienci[i].KlientId = Convert.ToInt32(tabelaK.Rows[i][0]);
                Klienci[i].imie = Convert.ToString(tabelaK.Rows[i][1]);
                Klienci[i].nazwisko = Convert.ToString(tabelaK.Rows[i][2]);
            }
            return Klienci;
        }

        private Film[] DataF_TabelaF (DataTable tabelaF)
        {
            for (int i=0; i<tabelaF.Rows.Count; i++)
            {
                Filmy = new Film[tabelaF.Rows.Count];
                Filmy[i].FilmId = Convert.ToInt32(tabelaF.Rows[i][0]);
                Filmy[i].Rezyser = Convert.ToString(tabelaF.Rows[i][1]);
                Filmy[i].Tytul = Convert.ToString(tabelaF.Rows[i][2]);
                Filmy[i].Cena = Convert.ToInt32(tabelaF.Rows[i][3]);
            }
            return Filmy;
        }

        private Egzemplarz[] DataE_TabelaE (DataTable tabelaE)
        {
            for (int i = 0; i < tabelaE.Rows.Count; i++)
            {
                Egzemplarze = new Egzemplarz[tabelaE.Rows.Count];
                Egzemplarze[i].EgzId = Convert.ToInt32(tabelaE.Rows[i][0]);
                Egzemplarze[i].FilmId = Convert.ToInt32(tabelaE.Rows[i][1]);
            }
            return Egzemplarze;
        }

        private Wypozyczenie[] DataW_TabelaW (DataTable tabelaW)
        {
            for (int i=0; i<tabelaW.Rows.Count;i++)
            {
                Wypozyczenia = new Wypozyczenie[tabelaW.Rows.Count];
                Wypozyczenia[i].KlientId = Convert.ToInt32(tabelaW.Rows[i][0]);
                Wypozyczenia[i].EgzId = Convert.ToInt32(tabelaW.Rows[i][1]);
            }
            return Wypozyczenia;
        }
    
    }


When I try to use:
bazaDVD sthnk = new bazaDVD();
     string elo = Convert.ToString(sthnk.Klienci.Length);
     MessageBox.Show(elo);

I get
An unhandled exception of type 'System.NullReferenceException'
Posted
Comments
Maciej Los 24-Oct-15 17:04pm    
Have you tried to debug the programme? As per my first look, you didn't defined full path to the database (extension is wrong?!?). On the other hand, using sql queries in code enables your app to SQLInjection.
Have a look here: http://stackoverflow.com/questions/20017688/why-we-do-sqlitecommand-parameters-add-while-we-can-use-string-format-to-compos

Sorry, but your code is a disaster. Nevermind using SQLite, you clearly don't know how to code.

You're getting a null reference exception because Klienci is not instantiated. It's only instantiated inside this loop:
C#
Klienci = new Klient[tabelaK.Rows.Count];

so if there are no rows, Klienci will be null.

Of course, you're instantiating for every single record, it should be instantiated outside of the loop, so you're never going to get the data into an array anyways.

And why would you want it in an array?

This:
C#
string elo = Convert.ToString(sthnk.Klienci.Length);
MessageBox.Show(elo);

is sort of a disaster too. You could just do:
MessageBox.Show(sthnk.Klienci.Length.ToString());

or:
MessageBox.Show(String.Format("Length = {0}", n));


So, sorry to say, it's not SQLite that is the problem, it's your code.
 
Share this answer
 
v4
Comments
Member 12084378 24-Oct-15 18:00pm    
Thanks for your help - I know I'm not a programmer, I'm just starting to try to be, and I'ts my first steps (sorry for my English too).

Anyway - I trasfer this:
<pre>Klienci = new Klient[tabelaK.Rows.Count];</pre>
above the loop, but there is still null-exception. Why?

MessageBox... was created only for checking - so it's no important.

And - why in an array? I don't know, I have to create SQLite database with DVD shop clients, and I thought it's the simplest way to add, find etc. clientes and movies with the arrays. I know array operations, I thought it will be easy to make arrays, then make operations I need, and finally save arrays to database back.
Marc Clifton 24-Oct-15 19:19pm    
What I would suggest is step through the program with the debugger - watch what Klienci is as you walk through each line of code, and see why it doesn't initialize. Also, creating an array with potentially 0 items is probably not a good ideas. If you need manage this stuff in an array-like manner, I'd suggest something like List<klient> klienci =new List<klient>(); and then you can do klienci.Add(...whatever...)

Which reminds me, after you do: klienci = new Klient[...some number], all that does is initialize the array. You still have to initialize each element of the array:

klienci[i] = new Klient();

Now you can assign the properties of the instance at [i]:

klienci[i].id = ...whatever...

So it's always a three step process, even with List<>:
1. instantiate the list or array
2. for each item, instantiate the class
3. for each instantiated class, initialize the properties.

Normally, step 3 is folded into the step 2 as part of the constructor parameters or as property initializers, like new Klient() {Id = 5};
You did not show where the exception with the message "Object reference not set to an instance of an object" is thrown.

Not to worry. This is one of the very easiest cases to detect and fix. It simply means that some member/variable of some reference type is dereferenced by using and of its instance (non-static) members, which requires this member/variable to be non-null, but in fact it appears to be null. Simply execute it under debugger, it will stop the execution where the exception is thrown. Put a break point on that line, restart the application and come to this point again. Evaluate all references involved in next line and see which one is null while it needs to be not null. After you figure this out, fix the code: either make sure the member/variable is properly initialized to a non-null reference, or check it for null and, in case of null, do something else.

Please see also: want to display next record on button click. but got an error in if condition of next record function "object reference not set to an instance of an object".

Sometimes, you cannot do it under debugger, by one or another reason. One really nasty case is when the problem is only manifested if software is built when debug information is not available. In this case, you have to use the harder way. First, you need to make sure that you never block propagation of exceptions by handling them silently (this is a crime of developers against themselves, yet very usual). The you need to catch absolutely all exceptions on the very top stack frame of each thread. You can do it if you handle the exceptions of the type System.Exception. In the handler, you need to log all the exception information, especially the System.Exception.StackTrace:
http://msdn.microsoft.com/en-us/library/system.exception.aspx,
http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx.

The stack trace is just a string showing the full path of exception propagation from the throw statement to the handler. By reading it, you can always find ends. For logging, it's the best (in most cases) to use the class System.Diagnostics.EventLog:
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx.

Good luck,
—SA
 
Share this answer
 
Please, read my comment first, becuase your application is SQLInjection[^] vulnerable. You should protect your data as much as possible.

1)
As the documentation states, connection string has to contain fully qualified path to the database!
C#
string connstring = string.Format("Data Source={0};Version=3;", "FullPathToTheDatabaseFile");

Note that, version of database is included. In case when you missed it, the default version is used (2).
See: https://www.connectionstrings.com/sqlite/[^]

Some developers recommend to use SQLiteConnectionStringBuilder[^] to ensure a correctly formatted string.
C#
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.FailIfMissing = true;
builder.DataSource = "FullPathToTheDatabase.db";
SQLiteConnection connection = new SQLiteConnection(builder.ConnectionString);
connection.Open();


2)
Do not use array of Klient, Film, Egzemplarz, Wypozyczenie. Rather than it, use List(of CustomClass). Please, see: List<T> generic class[^], which is more efficient, flexible, and provides a methods to sort and filter data.
Another option is to use custom class collection. See: Walkthrough: Creating Your Own Collection Class[^]
 
Share this answer
 
Ok Guys - you're my heroes. It works now, of course I didn't initialize class object Klient in loop, thanks you very much!
A changed it to List, I changed Version od database and I'm happy, thanks a lot!
 
Share this answer
 
Comments
Maciej Los 26-Oct-15 3:04am    
This is not an answer. Please, delete it to avoid down-voting. If you want to say "thank you", use "Have a question or comment" widget.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900