Compare the performance of the int, long, and byte data types in C#

[performance]

The example Compare the performance of the float, double, and decimal data types in C# compares the performance of the float, double, and decimal data types. This example performs a similar test for the int, long, and byte data types.

When you enter the number of trials that you want to perform and click the Go button, the following code executes.

// Compare performances.
private void btnGo_Click(object sender, EventArgs e)
{
    txtTimeFloat.Clear();
    txtTimeInt.Clear();
    txtTimeLong.Clear();
    txtTimeByte.Clear();
    Cursor = Cursors.WaitCursor;
    Refresh();

    int num_trials = int.Parse(txtNumTrials.Text);
    Stopwatch watch = new Stopwatch();
    float float1, float2, float3;
    int int1, int2, int3;
    long long1, long2, long3;
    byte byte1, byte2, byte3;

    watch.Start();
    int float_trials = num_trials / 10;
    for (int i = 0; i < num_trials; i++)
    {
        float1 = 1.23f;
        float2 = 4.56f;
        float3 = float1 / float2;
    }
    watch.Stop();
    txtTimeFloat.Text = "~" +
        (10 * watch.Elapsed.TotalSeconds).ToString() + " sec";
    txtTimeFloat.Refresh();

    watch.Reset();
    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        int1 = 7331;
        int2 = 1337;
        int3 = int1 / int2;
    }
    watch.Stop();
    txtTimeInt.Text =
        watch.Elapsed.TotalSeconds.ToString() + " sec";
    txtTimeInt.Refresh();

    watch.Reset();
    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        long1 = 73317331;
        long2 = 13371337;
        long3 = long1 / long2;
    }
    watch.Stop();
    txtTimeLong.Text =
        watch.Elapsed.TotalSeconds.ToString() + " sec";
    txtTimeLong.Refresh();

    watch.Reset();
    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        byte1 = 231;
        byte2 = 123;
        byte3 = (byte)(byte1 / byte2);
    }
    watch.Stop();
    txtTimeByte.Text =
        watch.Elapsed.TotalSeconds.ToString() + " sec";
    txtTimeByte.Refresh();

    Cursor = Cursors.Default;
}

The most interesting part of the code performs a simple mathematical operation inside loops for each of the data types. The program also executes a similar loop for the float data type for comparison. Because the float loop is a lot slower than those that use the other data types, the code divides the number of iterations by 10 for float and then multiplies the elapsed time by 10.

Before running the program I thought that int would be faster than long, but I didn’t expect int to take only a third as long as long. I also didn’t expect the byte data type to have roughly the same performance as the int data type.

Note that operations involving byte always return the int data type so the code must cast the result back into the byte data type. Even with the extra cast operation, byte is about as fast as int.

The moral is, use the int type instead of long if you can. (Note that the results may be different on different computers.)


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in performance, variables | Tagged , , , , , , , , , , , | Leave a comment

Compare the performance of the float, double, and decimal data types in C#

[performance]

A computer’s math coprocessor typically gives the best performance with a particular data type. To see which works best on my system and to learn how big the difference is, I wrote this program to compare the performance of calculations that use the float, double, and decimal data types.

Enter a number of trials and click the Go button to execute the following code.

// Compare performances.
private void btnGo_Click(object sender, EventArgs e)
{
    txtTimeFloat.Clear();
    txtTimeDouble.Clear();
    txtTimeDecimal.Clear();
    Cursor = Cursors.WaitCursor;
    Refresh();

    int num_trials = int.Parse(txtNumTrials.Text);
    Stopwatch watch = new Stopwatch();
    float float1, float2, float3;
    double double1, double2, double3;
    decimal decimal1, decimal2, decimal3;

    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        float1 = 1.23f;
        float2 = 4.56f;
        float3 = float1 / float2;
    }
    watch.Stop();
    txtTimeFloat.Text =
        watch.Elapsed.TotalSeconds.ToString() + " sec";
    txtTimeFloat.Refresh();

    watch.Reset();
    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        double1 = 1.23d;
        double2 = 4.56d;
        double3 = double1 / double2;
    }
    watch.Stop();
    txtTimeDouble.Text =
        watch.Elapsed.TotalSeconds.ToString() + " sec";
    txtTimeDouble.Refresh();

    // Scale by a factor of 10 for decimal.
    num_trials /= 10;
    watch.Reset();
    watch.Start();
    for (int i = 0; i < num_trials; i++)
    {
        decimal1 = 1.23m;
        decimal2 = 4.56m;
        decimal3 = decimal1 / decimal2;
    }
    watch.Stop();
    txtTimeDecimal.Text = "~" +
        (watch.Elapsed.TotalSeconds * 10).ToString() + " sec";

    Cursor = Cursors.Default;
}

The code starts by clearing its result text boxes and getting the number of trials desired. It then runs a loop that performs a simple mathematical operation on float variables and displays the elapsed time. It then repeats those steps for the double data type.

Next the code repeats the loop for the decimal data type. After running the program, I discovered that the decimal data type was much slower than the other types. To run in a reasonable amount of time for the decimal data type, the program divides the number of trials by 10 and then multiplies the elapsed time by ten.

If you look closely at the picture, you’ll see that to perform 100 million calculations the program used about 0.45 seconds for the float data type, about 0.60 for the double data type, and an estimated 22.04 seconds for the decimal data type.

The moral is, if you want performance, use float. If you need greater accuracy, use double. The performance difference isn’t that big anyway.

If you need a lot of accuracy and are willing to wait a lot longer, use decimal. At least on my computer. If you run the program on your computer and discover that double or decimal gives a faster result than float, please post a comment below.

Note that all of these calculations are fast. Even decimal took only about 1/5 of a microsecond per calculation. That means speed will only be an issue for programs that perform a huge number of calculations.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in performance, variables | Tagged , , , , , , , , , , | 6 Comments

Save several images into Access in C#

[save several images]

The example Save images in an Access database in C# includes an Access database. Unfortunately if you save several images into the database and then open the database in Access, Access removes the images. It just doesn’t seem to understand image data.

To make using the database easier, the example program includes a Load All button that loads several images at once. It loads one picture for each of the records in the Books table. The program uses the following code to load those images.

// Load images for all of the records.
private void btnLoadAll_Click(object sender, EventArgs e)
{
    string[] titles =
    {
        "Advanced Visual Basic Techniques",
        "Beginning Database Design Solutions",
        ...
    };
    string[] filenames =
    {
        @"Images\avbts.jpg",
        @"Images\db_design_s.jpg",
        ...
    };

    this.Cursor = Cursors.WaitCursor;

    string image_dir = Path.GetFullPath(
        Path.Combine(Application.StartupPath, "..\\..")) + "\\";
    
    // Load the images.
    for (int i = 0; i < titles.Length; i++)
    {
        LoadRecordImage(titles[i], image_dir + filenames[i]);
    }

    this.Cursor = Cursors.Default;
    MessageBox.Show("Loaded " + titles.Length + " images.");
}

The method starts by creating two arrays, one holding the titles of books and the other holding the names of image files. The images are stored in the project’s Images subdirectory so the file names start with Images\.

After defining the arrays, the program uses the Path class’s Combine method to combine the application’s startup path with the relative path ..\.. to find the project directory. (The one containing the code, not the executable.) It then uses GetFullPath to turn the combined path into a valid fully-qualified path.

The code loops through the book titles, calling the LoadRecordImage method shown in the following code for each title and file name.

// Load one record's picture.
private void LoadRecordImage(string title, string filename)
{
    try
    {
        // Get the image.
        Bitmap bm = new Bitmap(filename);

        // Set the image in the database.
        title = title.Replace("'", "''");
        OleDbCommand cmd = new OleDbCommand(
            "UPDATE Books SET CoverImage=@Image WHERE Title='" +
            title + "'",
            Conn);

        // Create a byte array holding the image.
        byte[] image_bytes = ImageToBytes(bm, ImageFormat.Png);

        // Add the image as a parameter.
        OleDbParameter param = new OleDbParameter();
        param.OleDbType = OleDbType.Binary;
        param.ParameterName = "Image";
        param.Value = image_bytes;
        cmd.Parameters.Add(param);

        // Execute the command (with no return value).
        cmd.Connection = Conn;
        Conn.Open();
        cmd.ExecuteScalar();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        Conn.Close();
    }
}

The LoadRecordImage method loads a bitmap. It then creates a SQL UPDATE statement to save the bitmap in the Books record for the given title.

To do that, it creates an OleDbParameter object for the bitmap, defines its properties appropriately, and executes the UPDATE statement.

Note that inserting images into the database isn’t super fast so adding even the 17 images in this example takes a couple seconds.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in database, graphics, image processing, Office | Tagged , , , , , , , , , , , , , , , , , , | 1 Comment

Find .NET libraries for namespaces in C#


[.NET libraries]

Some namespaces have names that nicely match their .NET libraries. For example, the System.Drawing namespace is defined in the System.Drawing library.

Unfortunately a namespace’s name doesn’t always match the name of the .NET library that defines it. For example, the System.Security namespace is defined in the System.Core library. That’s not too big a deal because System.Core is included in new applications by default so you don’t need to add a reference to it before you can use the System.Security namespace.

A tougher example is the System.Windows.Interop namespace. It’s not obvious from its name that you need to add a reference to the the PresentationCore library to use that namespace.

One way to find out which .NET libraries you need to use for a namespace is to search the internet for terms such as, “what library defines System.Windows.Interop I’m pulling my hair out in frustration.” If you’re lucky, you’ll find someone else who had the same problem.

[C# 6.0 in a Nutshell]

Happily today I came across this page that lists the .NET libraries that go with various namespaces. It’s from the book C# 6.0 in a Nutshell. The page is:

So the next time you can’t figure out which .NET libraries to use to get the features of a particular namespace, give this page a try.



Follow me on Twitter   RSS feed   Donate




Posted in .NET, miscellany | Tagged , , , , , , , , | Leave a comment

Load images from an Access database in C#

[load images]

The post Save images in an Access database in C# explains how to save images in an Access database. This post explains how to load images from an Access display them.

Like previous examples, this program uses a SQL statement of the form SELECT * FROM Books WHERE... to select a record from the database. It uses the following code to display the image stored in the returned record’s CoverImage field.

Bitmap bm = BytesToImage((byte[])reader["CoverImage"]);
picCover.Image = bm;

This code simply fetches the data in the CoverImage field, casts it into an array of bytes, and passes it to the BytesToImage method to convert the bytes into a Bitmap. The following code shows the BytesToImage method.

// Convert a byte array into an image.
private Bitmap BytesToImage(byte[] bytes)
{
    using (MemoryStream image_stream = new MemoryStream(bytes))
    {
        Bitmap bm = new Bitmap(image_stream);
        image_stream.Close();
        return bm;
    }
}

This method creates a MemoryStream associated with the byte array. It creates a new Bitmap passing its constructor the MemoryStream, and returns the Bitmap.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in database, graphics, image processing, Office | Tagged , , , , , , , , , , , , , , , , , | 2 Comments

Save images in an Access database in C#

[save images]

This example shows how you can save images in an Access database.

The example Use filenames stored in a database to display images in C# shows how to display images by saving the image file names in a database and then loading the images when needed. That’s my preferred method for displaying images with records but it does have a few drawbacks.

For example, with this method the images are not included in the database so you cannot distribute all of the data in a single file. This method also requires you to change the code (or some sort of configuration setting) if you move the images so the program can still find them. It may also result in orphaned image files if you delete a record and don’t delete the corresponding image file.

This example shows how to save images inside an Access database. Similar techniques should work for other database types, although you may need to change a few details such as the image field’s data type.

This example’s database books.mdb has a single Books table that has a CoverImage field of type OLE Object. Unfortunately Access does not provide a way to initialize that field with an image. In fact, Access has a rather annoying problem (at least version 2007) which results in this warning:

IMPORTANT: If you open the database with Access, it will erase all of the image data in the CoverImage column.

The example program available for download can repopulate the CoverImage column for you so it’s okay to open the database in Access to see how it works (or better, make a copy of the database and open that), but this could be a real problem in a real application. It not only means you cannot easily change the table’s structure, but it also means you cannot easily examine and modify other data fields.

Assuming you’ve created an Access database with a table that has a field of type OLE Object, you can save images into that field. To do so, you must first convert the image into an array of bytes and then save the array using the data type OleDbType.Binary.

In this example, if you select a record and then click the Set Image button, the following code executes.

// Set the image for this record.
private void btnSetImage_Click(object sender, EventArgs e)
{
    if (ofdImage.ShowDialog() == DialogResult.OK)
    {
        try
        {
            // Display the image.
            Bitmap bm = new Bitmap(ofdImage.FileName);
            picCover.Image = bm;

            // Set the image in the database.
            // The CoverImage field has type OLE Object.
            string title =
                lstTitles.SelectedItem.ToString().Replace("'", "''");
            OleDbCommand cmd = new OleDbCommand(
                "UPDATE Books SET CoverImage=@Image WHERE Title='" +
                title + "'",
                Conn);

            // Create a byte array holding the image.
            byte[] image_bytes = ImageToBytes(bm, ImageFormat.Png);

            // Add the image as a parameter.
            OleDbParameter param = new OleDbParameter();
            param.OleDbType = OleDbType.Binary;
            param.ParameterName = "Image";
            param.Value = image_bytes;
            cmd.Parameters.Add(param);

            // Execute the command (with no return value).
            cmd.Connection = Conn;
            Conn.Open();
            cmd.ExecuteScalar();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            if (Conn.State != ConnectionState.Closed) Conn.Close();
        }
    }
}

This code displays an OpenFileDialog to let you pick an image file for the record.

If you select a file and click OK, the program loads the image into a Bitmap. It then builds a string holding the title of the book that is currently selected. It replaces single quotes (‘) with paired single quotes (”) in the title so the SQL statement that it builds next doesn’t have mismatched single quotes.

The code then composes a SQL INSERT statement of the form:

UPDATE Books SET CoverImage=@Image
WHERE Title='Beginning Database Design Solutions'

The code then calls the ImageToBytes method described shortly to convert the Bitmap into an array of bytes.

Next the program defines the parameter that is represented by the @Image part of the SQL UPDATE statement. To do that, it creates an OleDbParameter object. It sets the object’s type to Binary, its name to Image (the name used in the UPDATE statement), and its value to the image’s array of bytes. After creating the parameter, the program adds it to the command’s Parameters collection.

The code then connects the command to the database connection Conn, opens the connection, and executes the UPDATE command. This command doesn’t return any value so the program uses the ExecuteScalar method to execute it. (ExecuteScalar simply executes a command and doesn’t return anything.)

This code uses a try catch block to protect itself against errors such as the selected file not being an image file. The finally block closes the database connection if it is still open.

The following code shows the ImageToBytes method that converts an image into a byte array.

// Convert an image into a byte array.
private byte[] ImageToBytes(Image image, ImageFormat format)
{
    using (MemoryStream image_stream = new MemoryStream())
    {
        image.Save(image_stream, format);
        return image_stream.ToArray();
    }
}

This method creates a MemoryStream. It then uses the Image object’s Save method to save the image into the MemoryStream with the desired format. (The example uses the png format.)

The method then simply calls the MemoryStream object’s ToArray method and returns the result.

That’s how you save an image into the database. In my next post I’ll explain how the program recovers an image from the database.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in database, graphics, image processing, Office | Tagged , , , , , , , , , , , , , , , , , | 4 Comments

Use the Filter property to select image files in C#

[filter property]

This example is mostly intended to make it easier to find these filters. I use them a lot and it’s a pain to have to recreate them every time I need them.


When you click the Different Types button, the program sets an OpenFileDialog component’s Filter property to the following value and then displays the dialog.

Bitmaps|*.bmp|PNG files|*.png|JPEG files|*.jpg|GIF files|*.gif|TIFF files|*.tif|Image files|*.bmp;*.jpg;*.gif;*.png;*.tif|All files|*.*

This Filter property value lets the user look for specific image types such as BMP, PNG, or JPG. It also lets the dialog show all files. (It’s usually a good idea to allow the All Files option so the user can at least see all of the files in the dialog’s current directory.)

When you click the All Images button, the program sets the OpenFileDialog component’s Filter property to the following value and then displays the dialog.

Image files|*.bmp;*.jpg;*.gif;*.png;*.tif|All files|*.*

This Filter property value lets the user look for any image file type or all files.

When you click a button, the program sets the OpenFileDialog’s Filter property to the appropriate value and then displays it. For example, the following code shows how the program responds when you click the second button.

In both cases, after the program sets the appropriate Filter property value, it sets the dialog’s FilterIndex property to 0 to select the first filter. It then displays the dialog. If you select an image file and click Open, the program loads the image file an displays it.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in controls, dialogs, image processing | Tagged , , , , , , , , , , , , , , , , | Leave a comment

Use filenames stored in a database to display images in C#

[display images]

The reason so many people ask how to store and retrieve images in a database is that it’s hard. You need to use a special data type such as the BLOB (Binary Large Object) or MEMO data type depending on the database. You also need to convert images to and from a binary format. I plan to explain how to do this soon, but there’s actually a method that is much easier and in many ways more effective: simply store the images in files and store their file names in the database.

One of the biggest drawbacks to storing images in a database is that databases don’t provide tools for working with images. If you want to insert an image into a record, you need to write software to do that. If you want to edit an image, you need to extract it into a file, edit it with some other tool, and store it again in the database. If an image becomes corrupted somehow, for example, a program accidentally overwrites one image with the wrong one, you need to write software to display the images until you figure out what is wrong and then you need to write more software to fix the problem.

Storing file names in the database avoids all of those problems. It also gives you more flexibility about where the files actually are. For example, you could put some images on your hard drive, others that you need less often on a DVD, and others scattered around your intranet or the internet.

These things are all possible if you store images inside a database, but things are a lot simpler if you just store the images in normal files somewhere and then load them as needed. If you need to examine, edit, or replace images, they’re simple files so this is easy. You can also add images without even opening the database. The database only contains the file names, which are strings, so it can even let you search for particular images by name, something that you can’t do if the images are stored in a binary format.

There are two disadvantages to this method. First, you cannot distribute the data in a single big database file. You can distribute the images in a single zip file and put them all in one directory (or more if that makes sense), however, so this isn’t too big a problem. (You could also store them on a network or distributed more easily than you can with a database.

The second drawback to storing file names is that the data can become inconsistent. For example, if you delete a database record and forget to delete the corresponding image file, then that file will be sitting around taking up space but the program won’t be able to use it. Similarly you might add a new image file but then store its name in the database with a typo in it so the program won’t be able to find it. If the images are stored in a database, the images are in their records so these issues cannot arise. (For information about database design and issues such as data integrity during insertions and deletions, see my book Beginning Database Design Solutions.)

Enough talk. Time for some code.

The example Display database records without data binding in C# explains how to fetch a database record when the user picks one from a list. The only thing this example needs to add is the ability to fetch a record’s image. The following code shows how this example displays the selected record.

// Display information about the selected title.
private void lstTitles_SelectedIndexChanged(object sender, EventArgs e)
{
    if (lstTitles.SelectedIndex < 0) return;

    // Make a command object to get information about the title.
    string title = lstTitles.SelectedItem.ToString().Replace("'", "''");
    OleDbCommand cmd = new OleDbCommand(
        "SELECT * FROM Books WHERE Title='" +
        title + "'",
        Conn);

    // Execute the command.
    cmd.Connection = Conn;
    Conn.Open();
    OleDbDataReader reader = cmd.ExecuteReader();
    reader.Read();

    // Display the text data.
    txtURL.Text = reader["URL"].ToString();
    txtYear.Text = reader["Year"].ToString();
    txtISBN.Text = reader["ISBN"].ToString();
    txtPages.Text = reader["Pages"].ToString();

    // Display the cover image.
    string filename = reader["CoverUrl"].ToString();
    picCover.Image = new Bitmap(filename);

    // Clean up.
    reader.Close();
    Conn.Close();
}

Most of this code is similar to the code used by the previous example. See that post for information about how it works.

The blue code shows the new step. That code gets the image file’s name, loads the image into a Bitmap, and displays it in the PictureBox control named picCover. That’s all there is to it!

If you want to let the user edit records, you would need to add code to let the user select a new image and to save the image in the appropriate file, but that’s reasonably straightforward.

Hopefully I’ll show how to truly save and restore images in a database soon.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in database, graphics, image processing, user interface | Tagged , , , , , , , , , , , , , , | 2 Comments

Move and resize multiple rectangles in WPF and C#

[multiple rectangles]

The example Let the user move and resize a rectangle in WPF and C# shows how to let the user move and resize a single rectangle in a WPF program. This example extends that one to let you move and resize multiple rectangles.

See the earlier example for the basic idea.

This example makes a relatively simple modification. Instead of using a single rectangle, it uses a list containing multiple rectangles. The following code declares and initializes the list.

// The Rectangles that the user can move and resize.
private List<Rectangle> Rectangles;

// Make a list of the Rectangles that the user can move.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Rectangles = new List<Rectangle>();
    foreach (UIElement child in canvas1.Children)
    {
        if (child is Rectangle)
            Rectangles.Add(child as Rectangle);
    }

    // Reverse the list so the Rectangles on top come first.
    Rectangles.Reverse();
}

The program’s window hold a Canvas control that contains the Rectangle controls. It also contains a Border to show that you don’t need to let the user move every control.

The window’s Loaded event handler creates the list and then loops through the Canvas control’s children. It adds the Rectangle controls that it finds to the Rectangles list.

After it has examined all of the children, the method reverses the order of the Rectangle controls so they appear in the list in top-to-bottom order.

The following method determines what if anything is at a particular point.

// The part of the rectangle under the mouse.
private HitType MouseHitType = HitType.None;

// The Rectangle that was hit.
private Rectangle HitRectangle = null;

// If the point is over any Rectangle,
// return the Rectangle and the hit type.
private void FindHit(Point point)
{
    HitRectangle = null;
    MouseHitType = HitType.None;

    foreach (Rectangle rect in Rectangles)
    {
        MouseHitType = SetHitType(rect, point);
        if (MouseHitType != HitType.None)
        {
            HitRectangle = rect;
            return;
        }
    }

    // We didn't find a hit.
    return;
}

This method loops through the Rectangles list and calls the SetHitType method for each of the Rectangle controls in the list. If SetHitType finds that the target point is over a Rectangle, then FindHit saves the hit type and the Rectangle hit in form-level variables and exits.

The rest of the program is similar to the earlier example except it uses the Rectangle stored in the variable HitRectangle instead of the single Rectangle used by the earlier example. Download this example to see the rest of the details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in controls, graphics, wpf, XAML | Tagged , , , , , , , , , , , | Leave a comment

Display database records without data binding in C#

[database records]

Many programs use data binding to display database records. That method is easy (at least as far as the code you write is concerned), but it’s not very flexible. This example shows how you can display database records without data binding. It requires more code behind the scenes but gives you more direct control over what’s happening.

The example Initialize lists from databases without binding in C# explains the basic technique. See that post to learn how this program defines its database connection and initializes its ListBox with book titles.

The following code shows the program displays information about a book when the user selects it from the ListBox.

// Display information about the selected title.
private void lstTitles_SelectedIndexChanged(object sender, EventArgs e)
{
    if (lstTitles.SelectedIndex < 0) return;

    // Make a command object to get information about the title.
    string title = lstTitles.SelectedItem.ToString().Replace("'", "''");
    OleDbCommand cmd = new OleDbCommand(
        "SELECT * FROM Books WHERE Title='" +
        title + "'",
        Conn);

    // Execute the command.
    cmd.Connection = Conn;
    Conn.Open();
    OleDbDataReader reader = cmd.ExecuteReader();
    reader.Read();

    // Display the text data.
    txtURL.Text = reader["URL"].ToString();
    txtYear.Text = reader["Year"].ToString();
    txtISBN.Text = reader["ISBN"].ToString();
    txtPages.Text = reader["Pages"].ToString();

    // Clean up.
    reader.Close();
    Conn.Close();
}

The code builds a SQL SELECT statement to get all of the data from the Books table for the selected book. Note that it uses Replace to convert single quotes into pairs of single quotes in the book’s title. If the book’s title contains a single quote, as in “Visual Basic 2012 Programmer’s Reference,” that quote would match with the single quotes in the SELECT statement and confuse the database. Replacing quotes with pairs of quotes tells the database that a pair of quotes represents a single quote in the title’s value so the query will work properly.

After composing the SELECT statement, the code executes it, saving the result of the ExecuteReader method in an OldDbDataReader object. It then calls that object’s Read method to get the first (and only) result record.

The code finishes by copying the returned record’s values into the appropriate TextBox controls.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in controls, database, lists, user interface | Tagged , , , , , , , , , , , , , | 1 Comment