Database Applications in C# See the next slide for sample form elements (C# application), from the CPackers demo program. ToolStripMenuItems labels text boxes MenuStrip picturebox Action buttons radio buttons (in a Group Box) Unbound Listbox Bound Listbox Data grid combobox During the next few weeks you will learn how to use Visual Studio’s Visual C# to access a database through an interface standard called ADO.NET. You will be able to download two different C# projects from the course web site, each of which interfaces with a SQL Server database. The first (CPackers) contains a simple form, which interfaces with a single table and contains options to find and list players according to several different constraints. The second (CUniversity) is a multiform project that simulates typical actions performed by a university registrar. These actions include displaying, editing, adding, and deleting student records; adding or dropping courses; listing student schedules; and listing course rosters. The slides that follow provide general instructions in how build a C# solution and connect to a database using ADO.NET controls. You should supplement these instructions with the Visual Studio solutions available through the course’s web page at [ ]. There are also two books on reserve you can consult. Creating a C# program You should run all of your C# programs from the network share described in a previous email. Both you and I have access to it. This is useful if you need help since I can access your program directly. It is also how I will grade your final project. To create the proper network share: Right click on computer in your program menu and select Map network drive Choose drive letter N. In the Folder textbox enter \\fpsb\groupwork$ Click the Finish button. You will see a list of folders. Any programs for this course should be stored in the folder having your name. Start C# (Start Programs Microsoft Visual Studio 2010 Microsoft Visual Studio 2010). You can close the Start page. Select File New Project. In the left pane (under Installed Templates) select Visual C# Windows. In the middle pane select Windows Forms Application. Select the folder to contain your solution. Again, this should correspond to your folder on the network share. Press the Select Folder button Give the project a name Do NOT check the box associated with Create directory for solution. It is not necessary for this course and just creates another level of subfolders. Click OK. When you create a project for the first time, a form (form1) automatically appears. You can save it using any other name you wish as follows: Right click on the form and select properties. You will see a properties window appear to the right. Through this window you can change the name and text attributes of the form along with many other things. Just locate the entry identified by (Name) and enter whatever name you want your form to have. I usually start all form names with “frm…” to easily identify what identifiers correspond to forms. There’s a similar entry in the properties window identified by Text. Whatever you enter appears at the top of the form when the program runs. Then select File Save …as and specify the name of the form to save the changes to the solution. You can use the same form name You can then remove files corresponding to the old form name. IMPORTANT: You should do this BEFORE proceeding with any coding on that form! Adding gui elements to your form Select View Toolbox to get items that you can drag to the form Expand All Windows Forms to see your options. Drag and drop items onto the form as needed. After you drag a gui element to the window, you can right click on it and select Properties. This allows you to easily change properties, including the element name. IMPORTANT: You should name ALL elements appropriately BEFORE moving ahead with any of your own coding. You can double click on the form to see the code associated with the form and create a form_load method. This code will be executed each time the form is loaded. This is useful if you need information in the form when the program first runs. You can return to viewing the form in design view by selecting the Design tab at the top of the window. Most of the code you write will be associated with button clicks. To do this: Drag and drop a button to your form. Give it a name through the properties window. Double click on the button to create an onclick method for it. Enter code as needed. Example Create a textbox (name it txtCount) and a button (name it btnCount). Insert the following into the form_load method txtCount.Text = “20”; Insert the following into the button click method int temp; temp = Int32.Parse(txtCount.Text); temp++; txtCount.Text = temp.ToString(); Run the program (F5 key) and press the button to increment the count. To open an existing C# project, double click on the sln file in the project folder. NOTE: To see file extensions you may need to do the following: With your folder open choose Organize Folder and search options. Select the view tab. Uncheck the box associated with Hide extensions for known file types. If, after opening a solution, the form or code does not appear, open the solutions explorer via View Solution Explorer. A window appears identifying forms in the solution. You can double click on one or select view code to see its code. To define where form appears, select the StartPosition form property and set to manual. Then set the location properties to define where the form appears. You can experiment to understand the parameters. Interface standards for database access It’s important to note that these notes describe only one way to access a database. There are numerous other ways, but we will NOT cover them. Once you understand one set of standards, the others become much more accessible. ODBC (Open Database Connectivity Standard): Defines interface standards through which SQL commands and results can be sent and received. Historically, this helped make database processing independent of the data source (e.g databases such as Oracle, Access, SQL server, etc. -- or even spreadsheets). See Figures 11-1 and 11-2 on pages 429 and 431. Will not discuss ODBC architecture OLE DB (Object Linking and Embedding): ODBC was designed for table-like sources (limitation). Developed by Microsoft OLE DB provides a standardized object-oriented interface to a wider variety of data sources (such as spreadsheets, databases, ISAM and VSAM files, and nonrelational databases) Encapsulates the features and functionality (i.e. updates, query processing, index creation, etc.) of a DBMS into OLE DB objects. Vendors have much more flexibility. For example, a vendor can implement portions of a product to interact with OLE DB. Provides greater marketability. Can add functionality later, allowing growth. Object oriented, so is particularly suited to object oriented languages such as C#. See Figure 11-11 on page 438. ADO (Active Data Object). Many database apps used scripting languages such as VBScript. ADO allows the use of almost any language to access OLE BD functionality. Built on top of the OLE DB object model; many consider it easier to use than OLE DB. See Figure 11-15 on page 442. ADO.NET: http://msdn.microsoft.com/enus/library/h43ks021(VS.71).aspx Improvement on ADO that was developed as part of Microsoft’s .NET initiative. See prose on page 442 and Figures 11-16 and 11-17 on page 443. ADO.NET also provides the ability to create and process client-side in-memory databases called datasets. A dataset can also be through of as an inmemory disconnected view of data. Typically it is defined from a base table or a view. ADO.NET classes. The C# applications in this course interact with a SQL server database via instances of three classes from the toolbox: SqlConnection, SqlDataAdapter, and DataSet. These classes are optimized for SQL Server databases but some of the others (e.g. oleDbDataAdapter) provide access to a wider variety of data sources. There are other ways. For course goals, there’s really little difference in the coding. SqlConnection Class Allows the application to establish a connection to a remote database. It contains properties that define the database provider, server name, database name, and other things. SqlDataAdapter Class Provides methods to exchange data between the application and remote database. It relies on requests being formulated in SQL (Structured Query Language). Our approach here is to create one data adapter for each base table or view your application is going to query. DataSet Class It’s an in-memory cache of data. Represents the results of an SQL command that the data adapter sends to the DBMS through the SQLConnection object. The DataSet typically represents a copy of a database table or view. A DataSet can hold multiple tables but we will just use one table per DataSet. Figure 11-17 on page 443 shows how these classes are related. NOTE: changes to the dataset are NOT automatically reflected in the database! Any changes must specifically be written back to the database or go through a stored procedure (discussed later). This is typical of a disconnected model for database activity. Creating an SqlConnection Create a C# app as described above. Make the form design visible and make sure the toolbox is also visible. In the toolbox, expand Common Controls. Drag and drop SqlConnection onto the form. It will appear on the tray below the form. If SqlConnection does not appear in toolbox select Tools Choose Toolbox Items. Be patient, it may take some time. Make sure the .NET Framework Components tab is selected. Find SqlConnection in the list and check the box next to it. Click OK. Right click on the connection icon and select properties. Give it a name (such as conTest). From the menu associated with ConnectionString in the properties window, select <New Connection…>. In the resulting window select Microsoft SQL Server (SqlClient) as the data source. Select ICSD for the server name. Select the radio button Use Windows Authentication. Select the database name (e.g. CS451_packers for the first demo). Click the OK button. If interested, you can examine the connection string via the connection properties. Creating a data adapter Click on SqlDadaAdapter in the toolbox and drag and drop onto form. If it is not in toolbox select Tools Choose Toolbox Items and add it as you did the SQLConnection object previously. When the wizard appears, do the following: Specify the data connection (i.e. to which database you want to connect). Click next. Specify use SQL statements to indicate how the adapter should access the database. Click next. Enter the select command to specify what data is loaded into the DataSet. You can also use the query builder to create the SQL command. Click next and then Finish. Through the properties window, you can rename it (example, daTest) If querying from a view, make sure you maintain consistency between view attribute names and the select command. Inconsistencies can especially occur if someone alters the view after the data adapter is created! NOTE: You can right click on the data adapter icon in the tray and select preview data. In the preview window there is a preview button that will display the data. NOTE: I once had problems when the SQL command queried multiple tables. I never followed through on this, largely because I found it much easier (and probably much more efficient) to first create a view on the server side and specify it during the connection process. If you need data from multiple tables, I recommend creating a view derived from multiple tables. Creating a DataSet: Select the data adapter and, from the menu, select Data Generate DataSet. Select the tables you want to add to the data set and specify a data set name (i.e., dsTest). Click OK. NOTE: If you selected dsTest as the dataset name, it will show in the tray as dsTest1. The properties will show a dataSetName entry as dsTest and a (Name) entry as dsTest1. dsTest1 is the name of the dataset and identifies the instance of a dataset class. Your code uses this. dsTest is just a property of the dataset It’s a little confusing and you can click here for a more detailed explanation. Bottom line is that your C# code should use dsTest1. NOTE: If a data set is created from a view, check to see (double click on the dataset’s xsd entry in the solution explorer) whether any primary keys carried through from the original base tables. You may have to remove the primary key designation from the data set’s table if the view allows the primary key to be replicated. Right clicking on a field in the dataset and looking at properties also allows you to change some constraints (for example, a not null constraint) that may have carried over from the underlying base tables. NOTE: Creating data sets depend on the data adapter and creating a data adapter depends on the underlying tables or views. Changing one may necessitate a change in others. Proceed with caution when you make changes after the fact!!! Better yet, don’t make changes after the fact. Double click on the form and you will see a number of Using statements at the beginning of the code. You need to add two more: using System.Data.SqlClient using System.Data.SqlTypes You need them to access certain classes associated with SQL. See packers demo. GUI elements The toolbox contains many icons allowing you to display headings and data on a form. Various properties allow you to design the look you want by defining fonts, colors, and positions of objects. You need only drag and drop a toolbox item to your form. Some of the toolbox objects follow. Label is used for headings and such. You can play with colors and appearance by changing the properties of a label. Right click on the label and then select Properties to see some options. Typical label name is lblName textbox is often used for the display of a database record’s attribute or for input to the application. You can bind a textbox to a database record’s attribute for display. This means it will automatically display the contents of the current (defined by a currencyManager object described in the program demos) database record’s attribute in your form. If you change the current record then the textbox content changes automatically. To bind a textbox to a database record’s attribute Drag and drop the textbox icon onto the form and set properties as needed. Select (DataBindings) text from the Properties window. Click on the arrow and you will see some options that will let you select the data set name, table name, and field name. Choose the dataset associated with the form name under Other Data Sources!! Choose also the table name and attribute. There are other options but the one above is consistent with things I will describe later. If you choose other ways to bind I can’t guarantee your programs will perform as described in these notes!!! In order to actually see data within a bound textbox you will have to fill the dataset. To do this call the Fill method of a data adapter object and specify the data set name (ex: dsTest1) as an argument. This may be done in a form_Load method or as part of some other action. The format of the fill command is daName.fill(dsName); See the Cpackers solution for an example. You can also leave the databindings field of the textbox blank if you plan on writing code to define those properties or simply treat the textboxes as user inputs. The Cpackers program shows examples of both. Bound text fields display player attributes. An unbound text field allows the user to enter a position for a “who plays” button. If you want to navigate through records, you will need a currencyManager object as defined in the Cpackers program. It’s similar to a list iterator (if you’ve covered that) or even a subscript that defines a current position in an array. It must be bound to a specific dataset as shown in the form_Load method of the Cpackers solution. Button Allows you to create C# code, which can be activated by simply clicking on the button which appears on the form. To create a button for simple tasks, drag and drop a button object on the form. Give it an appropriate caption and name via its properties. To associate an action with the button, double click on the button while in Design view. A new window will appear showing the declaration for a method associated with a button click. For example, in the Packers database, there is a button named btnNext. Double click on it and a window appears showing code for a method named btnNext_Click(). If you do this for the first time you get an empty method (with the proper signature). You can then enter appropriate code. ComboBox allows you to create a popup listing of all attribute values from a table or to show items you specify in its properties. The Packers Demo has one of each. You need to modify the ComboBox properties to do either of these. Here are some options: Select dropDownList from the dropdownstyle property. If you want to specify your own entries in the ComboBox, click on the button next to the Items property. Enter what you want. If you want the contents of table attributes to appear, modify the DataSource property to select the proper DataSet (again -- associated with the form) Then change the DisplayMember property to select the proper table and field. NOTE: To see the data you have to fill the dataset as described previously. A nice advantage of the combobox defined in this way is that it allows the user to locate a database record by selecting one of the combobox values. The located record is then established as current and any other bound controls that depend on the current record will update. See Packers demo RadioButtons and GroupBoxes allow you to select exactly one of several options on a form. C# code can then examine which option button was clicked and take action accordingly. To group radio buttons, drag and drop a GroupBox object onto the form. Then drag and drop RadioButton objects into the GroupBox object. C# code can access each button’s Checked property which is set to True or False, according to whether the button has been checked. Only one RadioButton in a GroupBox may be checked. DataGrid allows the display of a table. The table could be a base table, a view, or the result of an SQL query. Typically, the DataSource and DataMember properties of a dataGrid allow you to specify a data set and the table you want to appear in the grid. By default, all fields in the table will appear with default headings. You can alter the appearance of a dataGrid and column headings by creating a DataGridTableStyle in your C# code and adding it to a TableStyles Property of the grid. The Packers demo shows an example. ListBox can be used as a free form output box. You can write or move any information you want to it. It also acts similar to an array of strings, allowing you to reference each line of output via a subscript. This allows you to store information in a listbox and later rearrange it. For example, if lstTest is the ListBox name then lstTest.Items.Add(stringvariable) will add stringvariable to the end of the ListBox. The command lstTest.Items.Removeat(position) will remove the string at the indicated position. A listbox can also be used in a manner similar to that of the combobox by setting the dataSource and displayMember properties appropriately. MenuStrip can be used to create pull-down menus. Select MenuStrip from the toolbox and drag it to the form. Once the strip is on the form, it will show a “type here” combo box that allows you to add menu strip items. For our purpose here, you can select MenuItem to add tool strip menu items. If you select MenuItem you can give it an appropriate name and text attribute through the properties window. Also, if you select that item, you can then enter (by typing) choices you want to appear for that particular tool strip menu item object. If you then double click on the appropriate tool strip menu item, Studio creates an event handling method to respond to that selection. You can enter code in that method to respond to menu selections PictureBox Displaying other than text data, such as a photograph, can be done using a PictureBox object. It has methods that allow C# code to access files (such as JPG files) and display them in the PictureBox object. See the Packers demo for examples. To add a new form: In solution Explorer right click on the application name and select Add Windows form. Select windows forms under BOTH installed templates and within the middle pane; provide a name for the form. Press the Add button If a solution has multiple forms, one must be designated as the startup form. To select the startup form look for something like Program.cs at the bottom of the solution explorer window. Double click on that entry to see the code. Look for the Application.Run(…) line of code and specify your startup form as a parameter to the Run method.