Click here to Skip to main content
15,882,163 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Please excuse my analogy of birth certificates I used it for any novice like myself that might read this question.
I have two projects a VB.Net project DBCall and a Class Library Project DBControl.
When I create the DB Table the primary key is an Integer.
This Integer is placed in a DataGridView as a String and Converted to a Integer
when I select a Cell.
ID = Convert.ToInt32(dgvPerson.Rows[e.RowIndex].Cells[0].Value.ToString());

on the same form that does the conversion I declare a this variable.
public static int ID;
Now I navigate to another form frmADE where I use the ID.
This form wants to see the birth certificate where the ID was born.
So I need to use this line of code ID = frmSelect.ID;
This line of code is on frmADE public static int ID { get; set; }
Now we go to the form in the Class Library Project named frmHDB.
Hide();
 var form = new DBControl.frmHDB();
 {
     form.readData();
     ID = frmSelect.ID;
     textBox1.Text = "ID here " + ID + "";
 }

 Show();

This new State does not like or want to know about frmSelect where ID was born. I also have the same public static int ID {get;set;} on frmHDB
here is the readData() function and a line of code to get frmSelect recognized private object frmSelect;
public void readData()
{
    using (SQLiteConnection conn = new SQLiteConnection($"Data Source = '{dbName}';Version=3;"))
    {
        conn.Open();
        using (SQLiteCommand cmd = new SQLiteCommand($"SELECT * FROM FriendsData WHERE FID=" + frmSelect.ID, conn))
        {
            using (var rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    fn = rdr["fxFirstName"].ToString().Trim();
                    ln = rdr["fxLastName"].ToString().Trim();
                    rt = rdr["fxInfo"].ToString().Trim();
                }
            }
        }
    }
    Close();
}


I have tried to not use frmSelect and just the ID no Luck
I have use a number and the code works it populates the frmADE with data.
Tried writing a singleton function to transfer the ID not real good at this.
Tried creating a new instance of frmSelect so Class Library form would accept it.
I would like to know how to use forms from another project in Class Library?
I would like to know how to transfer int from one Project to the Class Library?

This Link and my ramblings in my solution might offer some insight
about how the SQLite was installed in these combined projects.
C# call CRUD functions on another form[^]

What I have tried:

I have tried to not use frmSelect and just the ID no Luck
I have use a number and the code works it populates the frmADE with data.
Tried writing a singleton function to transfer the ID not real good at this.
Tried creating a new instance of frmSelect so Class Library form would accept it.
Posted
Updated 3-Apr-23 16:16pm

First off, don't use static for your ID - that means there is only one per application and that's not necessarily the case when you create instances of the form as your code does.

Secondly, Never concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Always use Parameterized queries instead.

When you concatenate strings, you cause problems because SQL receives commands like:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
The quote the user added terminates the string as far as SQL is concerned and you get problems. But it could be worse. If I come along and type this instead: "x';DROP TABLE MyTable;--" Then SQL receives a very different command:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Which SQL sees as three separate commands:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';
A perfectly valid SELECT
SQL
DROP TABLE MyTable;
A perfectly valid "delete the table" command
SQL
--'
And everything else is a comment.
So it does: selects any matching rows, deletes the table from the DB, and ignores anything else.

So ALWAYS use parameterized queries! Or be prepared to restore your DB from backup frequently. You do take backups regularly, don't you?

Thirdly, why are you creating an instance of the form at all - you don't display it! Make readData static and pass it the ID value instead, and you don't need the form there so you decouple the classes from each other.

So: fix the first second one throughout your whole app, then:
1) Create a small class that holds the info the readData method has to return:
C#
public class UserData
   {
   public string FirstName {get; set;}
   public string LastName {get; set;}
   public string Info {get; set;}
   }

2) Create an instance of the "select" form.
3) Use ShowDialog to display it.
4) If the DialogResult shows the use clicked "OK" then:
4.1) Fetch the ID from the form Property.
4.2) Call the static ReadData method and pass it the ID value.
4.3) ReadData creates an instance of the UserData class and populates it from the database using the ID parameter.
4.4) ReadData returns the instance
4.5) Your code then processes the strings.

That way, your forms and other classes don't need to know about each other except where they actually need to: an OOPs design!

In your code, it's a mess of interrelated classes that need to know what the class calling them is doing, which is a very bad idea!
 
Share this answer
 
Comments
Choroid 20-Mar-23 15:54pm    
Griff Great it Works! As long as I only want one record and I do not close the app.
I added a UserData Class with additional line of code public UserData() {} in the frmSelect.
The issue is the ID is not being transferred to frmADE and as of now I have a nullpointer in the Class Library when I try to readData. I think the issue is because when I first built this I had the DB in the Class Library ONLY and when I added it the error was sqlite interop dll not found.
I deleted SQLite and reinstalled NuGet then wanted it installed inboth Projects.
If I detach the Class Library and put SQLite in this project only that might work
BUT the issue is the frmSelect loads the DataGridView and I do not know how to populate the
DGV Rows in another form or Class Library so until I can solve that putting the DB in the
Class Library project will not work. The time you spent on this answer is GREATLY appreciated
My best wished to you and herself. Consolation I learned how to construct UserData Class yea
OriginalGriff 21-Mar-23 3:20am    
And what do you expect
public UserData() {}
to do?
It declares a method called UserData which does nothing at all, not a class.

I think you need to go back to your course notes and refresh your self on what a class is and how you use it ...
Choroid 21-Mar-23 13:44pm    
Griff agreed it does nothing I found the code on CP and just copied it without knowing how it works
Lots to learn still looking for a good FREE book or a course that covers a wide range of topics
Tutorials Teacher has been the best site Thanks
The issue from my point of view as a novice learning C# and how to use the
Class Library is most code I looked at the design was to get data from the
Class Library most times I did not find code passing data into the Class Library.
I found one post where the novice like me wanted to Update Text Box With a new
string of text! Wait if he can update a textbox with a new string I can certainly
pass in a Database integer ID and use it to extract records from a database.
Here is the little method I placed in the Class Library.
It takes the udID from the attached Project and assigns it to local variable.
public void UTBW(int udID)
{
    newData = udID;
    return;
}

Then newData is used as the database ID
public void readUDV()
{
    using (SQLiteConnection conn = new SQLiteConnection($"Data Source = '{dbName}';Version=3;"))
    {
        conn.Open();
        using (SQLiteCommand cmd = new SQLiteCommand($"SELECT * FROM FriendsData WHERE FID = " + newData , conn))
        {
            using (var rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    fn = rdr["fxFirstName"].ToString().Trim();
                    ln = rdr["fxLastName"].ToString().Trim();
                    rt = rdr["fxInfo"].ToString().Trim();
                }
            }
        }
    }
}

When you click on a cell in a DataGridView you make the call to the Class Library with this code.
public void dgvPerson_CellClick(object sender, DataGridViewCellEventArgs e)
 {
     if (e.RowIndex == -1 | e.ColumnIndex == -1)
     {
         tbMessage.Text = "No Clicking Here";
         return;
     }
     else
     {
         ID = Convert.ToInt32(dgvPerson.Rows[e.RowIndex].Cells[0].Value.ToString());

         Close();
         frmADE fADE = new frmADE();
          udID = ID;
         if (doWhat == 2)
         {
             fADE.doWhat = 2;
             var form = new frmHDB();
             form.UTBW(udID);
         }

Then when frmADE loads using doWhat == 2 that just views the data here is that code
if (doWhat == 2)// View Selected Contact
 {
     using (var form = new frmHDB())
     {
         form.readUDV();
         setReadOnly();
         tbFirstName.Text = form.fn;
         tbLastName.Text = form.ln;
         rtbInfo.Rtf = form.rt;
         btnClose.Focus();
     }
 }

Thanks to Griff who provided the insight and steps to work on this code problem.
I learned one valuable lesson Class Library's are not all that portable from one
project to another. I attached the CL I created to another project and changed the
database name Guess What it changes it in the first project Took hours to figure out
why my first project was failing. I am still not sure this is the correct way to work
with Class Library's and a Project. I had to add the SQLite DB to both the CL and the
main project. This seemed very wrong I tried to add the System Data SQLite to just the
Class Library that created and issue where the interop dll were missing ? ?
How to fix this issue would be greatly appreciated in a comment PLEASE
 
Share this answer
 

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