Data

 <  Day Day Up  >  

Perhaps the greatest difference between Visual FoxPro and Visual Basic .NET is the handling of tables. It's a huge topic, and I'll just talk about general issues here. (It's covered in considerably more detail in Chapter 4, "A Visual Basic .NET Framework for SQL Server," and Chapter 7, "XML.") But I can give you a feel for the issues here.

FoxPro stores its data in either DBF files or in cursors . DBFs have a header of about 512 bytes that describes the nature of the table and its membership, if any, in a data base container (DBC). It then uses 32 bytes per field to describe all of the fields in the table. What follows are fixed-length records with a "delete byte" at the front, one per record. Cursors are in-memory representations of tables, having the same format except for the database container (DBC) information, which doesn't apply. When you USE a table or create a cursor using CREATE CURSOR or as the result of a SQL SELECT statement, FoxPro reads the header and uses its contents to interpret the fixed-length records that follow. BROWSE displays the table rows in a grid-like format.

Visual Basic .NET has no native data storage format. It always treats data as a foreign object. It usually reads it into a dataset, which is an XML representation of the data.

In its simplest form, XML consists of an XML header (a single line that says "I'm an xml string"), followed optionally by a Schema that describes the rows that follow, followed by a hierarchy of rows and fields that describe the table. A simple example follows:

 

 <?xml version = "1.0" encoding="Windows-1252" standalone="yes"?> <VFPData>    <xsd:schema id="VFPData" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  _      xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">       <xsd:element name="VFPData" msdata:IsDataSet="true">          <xsd:complexType>             <xsd:choice maxOccurs="unbounded">                <xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">                   <xsd:complexType>                      <xsd:sequence>                         <xsd:element name="name">                            <xsd:simpleType>                               <xsd:restriction base="xsd:string">                                  <xsd:maxLength value="20"/>                               </xsd:restriction>                            </xsd:simpleType>                         </xsd:element>                         <xsd:element name="phone">                            <xsd:simpleType>                               <xsd:restriction base="xsd:string">                                  <xsd:maxLength value="12"/>                               </xsd:restriction>                            </xsd:simpleType>                         </xsd:element>                      </xsd:sequence>                   </xsd:complexType>                </xsd:element>             </xsd:choice>             <xsd:anyAttribute namespace="http://www.w3.org/XML/1998/namespace" graphics/ccc.gif processContents="lax"/>          </xsd:complexType>       </xsd:element>    </xsd:schema>    <customer>       <name>Les Pinter</name>       <phone>650-344-3969</phone>    </customer> </VFProData> 

It looks scary, but if you saw the FoxPro DBF header it would be equally scary. Oh, what the heck. Figure 1.6 shows what the data that was displayed in XML looks like as a FoxPro .DBF.

Figure 1.6. The same data as a FoxPro .DBF.
graphics/01fig06.jpg

As you can see, neither one is really a "table." The program reads the file and uses it for whatever display mechanism you choose. As you can see, the tags that bracket each data element occupy quite a bit of space, compared to the positional format that fixed-length records permit; on the other hand, trimmed strings mean that extra blanks aren't transmitted. On balance, DBFs are somewhat smaller than their XML counterpart . So the idea that XML is less of a table than a DBF is just silly.

But the idea that XML is less efficient as a data storage mechanism is absolutely accurate. In fact, DBFs are extraordinarily efficient, especially when combined with the structural .cdx index files supported by FoxPro. I've demonstrated a SELECT that returned 30 matching records from more than a million in less than a tenth of a second. You can't get performance like that from SQL Server, which is a much more expensive data store. In some sense, XML is a dumbed-down DBF. Still, it does the job.

In FoxPro, on-screen controls use the ControlSource to bind to the data. Binding is bidirectional; change the contents of a text box, and the changes are automatically written back to the DBF. (There are a few caveats to observe, especially in multiuser environments, but this is basically how it works.) Grids have a RecordSource property that binds data to the grid in the same way that ControlSource does for controls.

Visual Basic .NET doesn't have tables or cursors. It has datasets. You fill a dataset by creating a SQLCommand or an OLEDBCommand object, specifying its SelectCommand CommandText , executing the SELECT , and then calling the Fill method of the Command object or DataAdapter object to fill the dataset. If that looks more complicated to you than USE (Table) , you're right.

But wait, there's more. A dataset can contain several tables; in that sense it's more like a form's Data Environment. In fact, it's a lot like a form's Data Environment. A dataset can also contain indexes and relations, just as the DE does.

Things stop being equally simple about here. You can bind a recordset to a DataGrid , but you have to tell it which of the tables in the recordset to bind to first. If you don't, you'll get a little plus sign that you click on to display all available tables and choose one. Or you can specify the table. Table(0) is the first table, so if there's only one table, it's always the same code. You can also select the DefaultView of the dataset, which is table(0) , and assign that to the DataGrid 's DataSource :

 

 SqlDataAdapter1.Fill(DsEmployee1) Dim dv As DataView dv = DsEmployee1.Tables(0).DefaultView DataGrid1.DataSource = dv 

This assumes that you previously dropped a SQLDataAdapter on the form and specified the connection to use to the ensuing wizard, and then right-clicked on the DataAdapter and selected Generate DataSet from the context menu, providing the name dsEmployee as the dataset name. Visual Basic .NET adds a 1 , because it always adds a 1 , even to the first instance of the class.

However, binding is one-way. In order to update the data source from whence the data came, you'll have to add code to get the changes made to the dataset and put them into a diffgram. Then you'll have to pass the diffgram to the SQLDataAdapter 's Update method, which was generated automatically when the DataAdapter was created. It's just a few more lines of code, but the fact that in FoxPro it's not necessary is notable.

But that's not entirely true. If you use DBFs it's not necessary. But if you use SQL or a Web service as the data store, you have to build a mechanism for executing the UPDATE statement that applies the changes that you made in the local cursor to the data store. So it's harder in Visual FoxPro as well.

The fact is that sending back new records or updates to a local table in Visual Basic .NET is exactly as difficult as sending them to SQL Server. So the programming cost saving of working with local tables in Visual Basic .NET is gone. You might as well print out the bill for some SQL Server licenses and hand them to your client.

 <  Day Day Up  >  


Visual Fox Pro to Visual Basic.NET
Visual FoxPro to Visual Basic .NET
ISBN: 0672326493
EAN: 2147483647
Year: 2004
Pages: 130
Authors: Les Pinter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net