0

I have a local database for a system / application I'm doing. Within this DB I have Books & Category Columns - CategoryID also makes part of the Books table as a Foreign Key, and I have 10 Category Records, for book genre, like 'Comics' (ID: 1), 'Crafts' (ID: 2), 'Education' (ID: 3), etc.

I am currently implementing an Add Book Record function in the application, so that when I save, a new book record is inserted in my DB with the details given, however, for CategoryID (in Books table), I can only input integers, which I don't want (as explained below)

(BTW, apologies but I'm still a coding newbie)

I have seen some tutorials on Enums, but I can't seem to find anything on how to combine an Enum with a combobox.

What I want is to have the combobox show something like:

1 - Comics, 2 - Crafts, 3 - Education, etc.

The above combobox dropdown list would point out to (for example) '1 - Comics' for CategoryID: 1, '2 - Crafts' for CategoryID: 2, and so on.

This is what I currently have outside of the Add New Record button

public partial class AddBookRecordForm : Form
{
    public AddBookRecordForm()
    {
        InitializeComponent();
    }

    enum BookCategory
    {
        Comics = 1,
        Crafts = 2,
        Education = 3,
        History = 4,
        Entertainment = 5,
        Thriller = 6,
        Religion = 7,
        Romance = 8,
        Fantasy = 9,
        Sports = 10
    }

Not sure how to proceed now - I'm assuming that the next part of code would need to be implemented within the Save Button Code.

For Reference, the below is the DB connection I did within the Save Button method.

 string ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename= 
 C:\Program Files\Microsoft SQL 
 Server\MSSQL14.SQLEXPRESS\MSSQL\DATA\Library System Project.mdf 
 ;Integrated Security=True;Connect Timeout=30";

        string Query = "insert into Books (BookName, BookAuthor, CategoryID, ClassificationID, BookAvailabilityQuantity, Price) values ('" + this.txtName.Text.Trim() + "','" + this.txtAuthor.Text.Trim() + "','" + this.txtCategory.Text.Trim() + "','" + this.txtClassification.Text.Trim() + "','" + this.txtAvailabilityQuantity.Text.Trim() + "','" + this.txtPrice.Text.Trim() + "');";

        SqlConnection DBCon = new SqlConnection(ConnectionString);
        SqlCommand DBCommand = new SqlCommand(Query, DBCon);
        SqlDataReader DBReader;

        try
        {
            DBCon.Open();
            DBReader = DBCommand.ExecuteReader();
            MessageBox.Show("New book record added to the system.", "Library System", MessageBoxButtons.OK);

            while (DBReader.Read())
            {

            }
        }

        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

        finally
        {
            // *** If you're going to be opening a connection be sure to close it ***
            // *** Finally blocks work well for this ***
            DBCon.Close();

            this.txtName.ResetText();
            this.txtAuthor.ResetText();
            this.txtCategory.ResetText();
            this.txtClassification.ResetText();
            this.txtAvailabilityQuantity.ResetText();
            this.txtPrice.ResetText();
        }
    }
avner1169
  • 41
  • 6
  • 1
    Possible duplicate of [Binding an enum to a WinForms combo box, and then setting it](https://stackoverflow.com/questions/906899/binding-an-enum-to-a-winforms-combo-box-and-then-setting-it) – Crowcoder May 19 '19 at 13:25
  • 1
    Your code has a major security flaw; it suffers from SQL Injection. Never inject values into your SQL Statement, always parametrise it; I suggest looking up `Parameters.Add`. – Thom A May 19 '19 at 13:25
  • Thank you @Larnu, I will look into it after I sort this combobox query. – avner1169 May 19 '19 at 13:29
  • 1
    Personally I see the injection issue as a far bigger problem. :) – Thom A May 19 '19 at 13:39
  • @Larnu, thanks again. Anyone can assist further on the enum / combobox thing, please? I'm really lost on this. – avner1169 May 19 '19 at 14:08
  • Yes @NatPongjardenlarp, I followed that link and am now getting this error: "the INSERT statement conflicted with the FOREIGN KEY constraint. – avner1169 May 19 '19 at 14:53
  • Have a look at [Little Bobby Tables](https://www.xkcd.com/327/) to see how your code is vulnerable to an attack. Try to use parameters with your queries. – Fabulous May 19 '19 at 14:53
  • Isn't the below (copied from above code) an insert query @NatPongjardenlarp? string Query = "insert into Books (BookName, BookAuthor, CategoryID, ClassificationID, BookAvailabilityQuantity, Price) values ('" + this.txtName.Text.Trim() + "','" + this.txtAuthor.Text.Trim() + "','" + this.txtCategory.Text.Trim() + "','" + this.txtClassification.Text.Trim() + "','" + this.txtAvailabilityQuantity.Text.Trim() + "','" + this.txtPrice.Text.Trim() + "');"; – avner1169 May 19 '19 at 15:53
  • That is a very different error @avnver1169 and should be a different question. – Thom A May 19 '19 at 15:57

1 Answers1

0

For simplicity I would suggest this as my quick soluction.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    enum BookCategory
    {
        Comics = 1,
        Crafts = 2,
        Education = 3,
        History = 4,
        Entertainment = 5,
        Thriller = 6,
        Religion = 7,
        Romance = 8,
        Fantasy = 9,
        Sports = 10
    }              

    private void Form1_Load(object sender, EventArgs e)
    {
        var values = Enum.GetValues(typeof(BookCategory));

        var dataSource = new List<BookCategoryData>();

        foreach (var bookCatergory in values)
        {
            dataSource.Add(new BookCategoryData() { Id = (int)bookCatergory, Name = bookCatergory.ToString() });
        }

        comboBox1.ValueMember = "Id";
        comboBox1.DisplayMember = "Name";
        comboBox1.DataSource = dataSource;

    }

    private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

    }
}

public class BookCategoryData
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Also as metioned here for other members please take a look on SQL Injection and use Sql Parameters in order to use concatenated text. Your code will looks like something below:

string query = "insert into Books (BookName, BookAuthor, CategoryID, ClassificationID, BookAvailabilityQuantity, Price) " +
"values (@BookName, @BookAuthor, @CategoryID, @ClassificationID, @BookAvailabilityQuantity, @Price)";

SqlCommand command = new SqlCommand(query, connection);
command.Parameters.Add("@BookName", this.txtName.Text.Trim());
Flavio Francisco
  • 755
  • 1
  • 8
  • 21
  • Thanks a lot for pointing out @Flavio, that's a great help. However, have tested myself, and still get the Foreign Key constraint by following the code you provided above. Not really sure what's triggering that - maybe the insert query I'm using is not correct?? – avner1169 May 19 '19 at 17:41
  • Foreign Key erros occurs when you are trying to insert a data into a table that doesn't exist on the Primary Key's table. Check what your INSERT is trying to insert and the values of either CategoryId or ClassificationId and see if they exist on its reference table. If you that is the answer, please mark this question as answered. Good luck. – Flavio Francisco May 19 '19 at 17:49
  • Each parameter must be included as well command.Parameters.Add("@BookName", this.txtName.Text.Trim()); command.Parameters.Add("@BookAuthor", this.txtAuthor.Text.Trim()); (...) – Flavio Francisco May 19 '19 at 17:54