Databinding
ODBC
Database
MySQL
Børre Stenseth
Moduler>Databaser>Vinbase

Finne vin

Hva
Image1
Databinding, database, navigasjon

I denne modulen henter vi vinbeskrivelser fra en database, kopler en liste med datasett mot en bindingSource og kopler denne mot en bindingNavigator. Vi kopler altså ikke direkte mot databasen, men lar automatikken jobbe mot et sett med objekter vi skaper.

Selve databsen er enkel og består av en tabell. Denne er dokumentert i modulen Noen datasett Vi bruker mySQL-versjonen [1] [2] av basen og gjør eksplisitte oppslag, se dbaccess.cs nedenfor.

Det er tre klasser som er koplet sammen for å gjøre jobben:

  • Form1.cs som setter opp GUI og plukker opp to beginvnheter: Når vi klikker på knappen som henter data fra databasen, og når vi klikker på en kontroll i bindigNavigator.
  • OneWine.cs som holder ett datasett, altså data for en vin.
  • dbaccess.cs som tar seg kommunikasjonen mot databasen.

Form1.cs

Denne klassen er slik:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Winebase
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void buttonShow_Click(object sender, EventArgs e)
        {
            // formulate the sql-query from the GUI-selections
            String Query = "select * from wines ";
            String AND="";
            String WHERE = "where";
            // do type
            if(checkBoxRed.Checked||checkBoxWhite.Checked
                ||checkBoxRose.Checked||checkBoxSparkling.Checked)
            {
                AND = " and ";
                Query += WHERE +" (";
                WHERE = "";
                if (checkBoxRed.Checked)
                    Query += "( type=\"red\") or ";
                if (checkBoxWhite.Checked)
                    Query += "( type=\"white\") or ";
                if (checkBoxRose.Checked)
                    Query += "( type=\"rose\") or ";
                if (checkBoxSparkling.Checked)
                    Query += "( type=\"sparkling\") or ";
                Query=Query.Substring(0,Query.Length-4)+")";
            }
            // do country
            String country = (string)comboBoxCountry.SelectedItem;
            if (country.Contains("Alle"))
                country = ";";
            else
                country = WHERE+AND+" (country=\"" + country+"\");";
            Query = Query + country;
            // show sql, just for inspection
            labelSQL.Text ="sql: "+ Query;
            dbaccess.MakeWineList(Query, bindingSource1);
        }
        private void bindingSource1_CurrentChanged(object sender, EventArgs e)
        {
            if (bindingSource1.Current != null)
            {
                textBoxDescription.Text =
                    ((OneWine)bindingSource1.Current).Description;
                textBoxCountry.Text =
                    ((OneWine)bindingSource1.Current).Type +
                    " vin fra " + ((OneWine)bindingSource1.Current).Country;
                textBoxName.Text =
                    ((OneWine)bindingSource1.Current).Name;
                pictureBox1.Image =
                    ((OneWine)bindingSource1.Current).Image;
                textBoxPrice.Text =
                    "kr " + ((OneWine)bindingSource1.Current).Price;
                textBoxVolume.Text = (
                    (OneWine)bindingSource1.Current).Volume + "cl";
            }
            else
            {
                textBoxDescription.Text ="";
                textBoxCountry.Text ="";
                textBoxName.Text = "";
                pictureBox1.Image =null;
                textBoxPrice.Text ="";
                textBoxVolume.Text ="";
            }
        }
    }
}

dbaccess.cs

Denne klassen består av en statisk metode. Denne metoden, MakeWineList, tar en SQL-setning og et BindingSource-obekt som parametere. Metoden utfører SQL-setningen og "fyller opp" BindingSource-objektet. Klassen er slik:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Odbc;
using System.Windows.Forms;
namespace Winebase
{
    class dbaccess:Object
    {
        static String connectString =
                    @"DRIVER={MySQL ODBC 3.51 Driver};
                    SERVER=frigg.hiof.no;
                    DATABASE=vin;
                    UID=student;
                    PASSWORD=student;
                    OPTION=3";
        public static bool MakeWineList(string query,BindingSource bs)
        {
            OdbcConnection con = null;
            OdbcDataReader myReader = null;
            bs.Clear();
            try
            {
                con = new OdbcConnection(connectString);
                con.Open();
                // execute a query
                OdbcCommand myCommand = new OdbcCommand(query, con);
                myReader = myCommand.ExecuteReader();
                // and process the results according to table-def:
                /*
                create table wines(
                    vin_id INT PRIMARY KEY AUTO_INCREMENT,
                    name VARCHAR(100),
                    catalog CHAR(10),
                    type CHAR(10),
                    country VARCHAR(20),
                    dice TINYINT,
                    volume INT,
                    price CHAR(10),
                    description TEXT
                );
                 */
                while (myReader.Read())
                {
                    String name=myReader.GetString(1);
                    String country = myReader.GetString(4);
                    String type=myReader.GetString(3);
                    String description = myReader.GetString(8);
                    int rating = myReader.GetInt16(5);
                    string price = myReader.GetString(7);
                    string volum = myReader.GetValue(6).ToString();
                    bs.Add(
                        new OneWine(country,
                            type,
                            description,
                            rating,
                            name,
                            price,
                            volum));
                 }
                return true;
                
            }
            catch (Exception ex)
            {
                // error message
                MessageBox.Show(ex.Message, "ERROR",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;            
            }
            finally
            {
                if (con != null)
                    con.Close();
                if (myReader != null)
                    myReader.Close();
            }
        }
    }
}

OneWine.cs

Denne klassen er enkel. Den har som oppgave å holde data for en vin og gi fra seg disse som properties på forspørsel. Vi kunne, og burde kanskje, implementert denne som en struct.

using System;
using System.Collections.Generic;
using System.Text;

namespace Winebase
{
    class OneWine : Object
    {
        String country;
        String type;
        String description;
        int dice;
        string name;
        String price;
        string volume;
        public OneWine(string c,
            string t,
            string desc,
            int rating,
            string n,
            String pr,
            string vol)
        {
            country = c;
            type = t;
            description = desc;
            dice = rating;
            name = n;
            price = pr;
            volume = vol;
        }
        public string Country { get { return country; } }
        public string Type
        {
            get
            {
                if (type.CompareTo("red") == 0) return "Rød";
                if (type.CompareTo("white") == 0) return "Hvit";
                if (type.CompareTo("rose") == 0) return "Rosé";
                return "Musserende";
            }
        }
        public string Description { get { return description; } }
        public int Dice { get { return dice; } }
        public string Name { get { return name; } }
        public string Price { get { return price; } }
        public string Volume { get { return volume; } }
        public System.Drawing.Bitmap Image
        {
            get
            {
                if ((type.CompareTo("red") == 0))
                {
                    switch (dice)
                    {
                        case 1: return Winebase.Properties.Resources.red1;
                        case 2: return Winebase.Properties.Resources.red2;
                        case 3: return Winebase.Properties.Resources.red3;
                        case 4: return Winebase.Properties.Resources.red4;
                        case 5: return Winebase.Properties.Resources.red5;
                        default: return Winebase.Properties.Resources.red6;
                    }
                }
                else if ((type.CompareTo("white") == 0))
                {
                    switch (dice)
                    {
                        case 1: return Winebase.Properties.Resources.white1;
                        case 2: return Winebase.Properties.Resources.white2;
                        case 3: return Winebase.Properties.Resources.white3;
                        case 4: return Winebase.Properties.Resources.white4;
                        case 5: return Winebase.Properties.Resources.white5;
                        default: return Winebase.Properties.Resources.white6;
                    }
                }
                else if ((type.CompareTo("rose") == 0))
                {
                    switch (dice)
                    {
                        case 1: return Winebase.Properties.Resources.rose1;
                        case 2: return Winebase.Properties.Resources.rose2;
                        case 3: return Winebase.Properties.Resources.rose3;
                        case 4: return Winebase.Properties.Resources.rose4;
                        case 5: return Winebase.Properties.Resources.rose5;
                        default: return Winebase.Properties.Resources.rose6;
                    }
                }
                else
                {
                    switch (dice)
                    {
                        case 1: return Winebase.Properties.Resources.sparkling1;
                        case 2: return Winebase.Properties.Resources.sparkling2;
                        case 3: return Winebase.Properties.Resources.sparkling3;
                        case 4: return Winebase.Properties.Resources.sparkling4;
                        case 5: return Winebase.Properties.Resources.sparkling5;
                        default: return Winebase.Properties.Resources.sparkling6;
                    }
                }
            }
        }
    }
}

Merk at alle bildene er lagt inn som gif-ressurser i selve applikasjonen. De plukkes fram basert på vintype og terningkast (dice).

Referanser
  1. MySQLmysql.comwww.mysql.com14-03-2010
  1. MySql i .NETMySqldev.mysql.com/tech-resources/articles/dotnet/14-03-2010
  • Prosjekt:
    https://svn.hiof.no/svn/psource/Csharpspikes/winebase
Vedlikehold

B.Stenseth, desember 2005

(Velkommen) Moduler>Databaser>Vinbase (Vinbase2)