Using the ADO.NET Interface

About this chapter

This chapter describes the ADO.NET interface and explains how to prepare to use this interface and how to define an ADO.NET database profile.

For more information

This chapter gives general information about using the ADO.NET interface. For more detailed information:

  • See the Data Access and .NET development sections in the Microsoft MSDN library at http://msdn.microsoft.com/en-us/data/default.aspx.

  • Use the online Help provided by the data provider vendor.

  • Check to see if there is a technical document that describes how to connect to your ADO.NET data provider.

About ADO.NET

ADO.NET is a set of technologies that provides native access to data in the Microsoft .NET Framework. It is designed to support an n-tier programming environment and to handle a disconnected data architecture. ADO.NET is tightly integrated with XML and uses a common data representation that can combine data from disparate sources, including XML.

One of the major components of ADO.NET is the .NET Framework data provider, which connects to a database, executes commands, and retrieves results.

Microsoft provides .NET Framework data providers for SQL Server and OLE DB with the .NET Framework, and data providers for ODBC and Oracle can be downloaded from the Microsoft website. You can also obtain .NET Framework data providers from other vendors, such as the .NET Framework Data Provider for Adaptive Server Enterprise from SAP.

To connect to a database using the PowerBuilder ADO.NET database interface, you must use a .NET Framework data provider.

Accessing Unicode data

Using the ADO.NET interface, PowerBuilder can connect, save, and retrieve data in both ANSI/DBCS and Unicode databases but does not convert data between Unicode and ANSI/DBCS. When character data or command text is sent to the database, PowerBuilder sends a Unicode string. The data provider must guarantee that the data is saved as Unicode data correctly. When PowerBuilder retrieves character data, it assumes the data is Unicode.

A Unicode database is a database whose character set is set to a Unicode format, such as UTF-8, UTF-16, UCS-2, or UCS-4. All data must be in Unicode format, and any data saved to the database must be converted to Unicode data implicitly or explicitly.

A database that uses ANSI (or DBCS) as its character set might use special datatypes to store Unicode data. Columns with these datatypes can store only Unicode data. Any data saved into such a column must be converted to Unicode explicitly. This conversion must be handled by the database server or client.

About the PowerBuilder ADO.NET database interface

You can use the PowerBuilder ADO.NET database interface to connect to a data source such as Adaptive Server Enterprise, Oracle, and Microsoft SQL Server, as well as to data sources exposed through OLE DB and XML, in much the same way as you use the PowerBuilder ODBC and OLE DB database interfaces.

Performance

You might experience better performance if you use a native database interface. The primary purpose of the ADO.NET interface is to support shared connections with other database constructs such as the .NET DataGrid in SAP DataWindow .NET.

Components of an ADO.NET connection

When you access a database using ADO.NET in PowerBuilder, your connection goes through several layers before reaching the database. It is important to understand that each layer represents a separate component of the connection, and that components might come from different vendors.

The PowerBuilder ADO.NET interface consists of a driver (pbado.dll) and a server (either Sybase.PowerBuilder.Db.dll or Sybase.PowerBuilder.DbExt.dll). The server has dependencies on a file called pbrth.dll. These DLLs must be deployed with an application that connects to a database using ADO.NET. For Oracle 10g or Adaptive Server 15 or later, use Sybase.PowerBuilder.DbExt.dll. For earlier versions and other DBMSs, use Sybase.PowerBuilder.Db.dll.

The DataWindow .NET database interface for ADO.NET supports the ADO.NET data providers listed in the following table.

Data Provider

Namespace

.NET Framework Data Provider for OLE DB

System.Data.OleDb

.NET Framework Data Provider for SQL Server

System.Data.SqlClient

Oracle Data Provider for .NET (ODP.NET)

Oracle.DataAccess.Client *

SAP ADO.NET Data Provider for Adaptive Server Enterprise (ASE)

SAP.Data.AseClient


* Oracle.DataAccess.Client is unsupported by transaction objects from C#. Oracle.ManagedDataAccess.Client is unsupported by transactions objects from PowerBuilder or C#. These problems exist in PowerBuilder 12.6, 2017, and 2019.

Additional .NET Framework data providers may be supported in future releases. Please see the release bulletin for the latest information.

The following figure shows the general components of an ADO.NET connection using the OLE DB .NET Framework data provider.

Figure: Components of an ADO.NET OLE DB connection

The following figure shows the general components of an ADO.NET connection using a native ADO.NET data provider.

Figure: Components of a native ADO.NET connection

OLE DB data providers

When you use the .NET Framework data provider for OLE DB, you connect to a database through an OLE DB data provider, such as Microsoft's SQLOLEDB or MSDAORA or a data provider from another vendor.

The .NET Framework Data Provider for OLE DB does not work with the MSDASQL provider for ODBC, and it does not support OLE DB version 2.5 interfaces.

You can use any OLE DB data provider that supports the OLE DB interfaces listed in the following table with the OLE DB .NET Framework data provider. For more information about supported providers, see the topic on .NET Framework data providers in the Microsoft .NET Framework Developer's Guide.

The PowerBuilder ADO.NET interface supports connection to SQL Anywhere, Adaptive Server Enterprise, Microsoft SQL Server, Oracle, Informix, and Microsoft Access with the OLE DB .NET Framework data provider.

After you install the data provider, you might need to define a data source for it.

OLE DB object

Required interfaces

OLE DB Services

IDataInitialize

DataSource

IDBInitialize

IDBCreateSession

IDBProperties

IPersist

Session

ISessionProperties

IOpenRowset

Command

ICommandText

ICommandProperties

MultipleResults

IMultipleResults

RowSet

IRowset

IAccessor

IColumnsInfo

IRowsetInfo (only required if DBTYPE_HCHAPTER is supported)

Error

IErrorInfo

IErrorRecords


Preparing to use the ADO.NET interface

Before you define the interface and connect to a database using ADO.NET:

  1. Install and configure the database server, network, and client software.

  2. Install the ADO.NET interface.

  3. Install Microsoft's Data Access Components version 2.6 or higher software on your machine.

Step 1: Install and configure the data server

You must install and configure the database server and install the network software and client software.

To install and configure the database server, network, and client software:

  1. Make sure the appropriate database software is installed and running on its server.

    You must obtain the database server software from your database vendor. For installation instructions, see your database vendor's documentation.

  2. Make sure the required network software (such as TCP/IP) is installed and running on your computer and is properly configured so that you can connect to the data server at your site. You must install the network communication driver that supports the network protocol and operating system platform you are using.

    For installation and configuration instructions, see your network or data source administrator.

  3. If required, install the appropriate client software on each client computer on which PowerBuilder is installed.

Client software requirements

To determine client software requirements, see your database vendor's documentation.

Step 2: Install the ADO.NET interface

If you install PowerBuilder using the PowerBuilder Installer (an online setup program), the ADO.NET interface is automatically installed. If you install PowerBuilder using the downloaded installation package (an offline setup program), select the ADO .NET Database Driver from the list of components.

Step 3: Install the Microsoft Data Access Components software

The PowerBuilder ADO.NET interface requires the functionality of the Microsoft Data Access Components (MDAC) version 2.8 or higher software.

To check the version of MDAC on your computer, you can download and run the MDAC Component Checker utility from the MDAC Downloads page at http://msdn.microsoft.com/en-us/data/aa937730.aspx.

OLE DB data providers installed with MDAC

Several Microsoft OLE DB data providers are automatically installed with MDAC, including the providers for SQL Server (SQLOLEDB) and ODBC (MSDASQL).

Defining the ADO.NET interface

Using the ADO.NET Database Profile Setup

To define a connection using the ADO.NET interface, you must create a database profile by supplying values for at least the basic connection parameters in the Database Profile Setup -- ADO.NET dialog box. You can then select this profile at any time to connect to your data in PowerBuilder.

For information on how to define a database profile, see Using database profiles.

Specifying connection parameters

You must supply a value for the Namespace and DataSource connection parameters and for the User ID and Password. When you use the System.Data.OleDb namespace, you must also select a data provider from the list of installed data providers in the Provider drop-down list.

The Data Source value varies depending on the type of data source connection you are making. For example, if you are using Microsoft's OLE DB Provider for SQL Server, you select SQLOLEDB as the Provider value and enter the actual server name as the Data Source value. In the case of Microsoft SQL Server, you must also use the Extended Properties field to provide the database name (for example, Database=Pubs) since you can have multiple instances of a database.

Using the Data Link API with OLE DB

The Data Link option allows you to access Microsoft's Data Link API, which allows you to define a file or use an existing file that contains your OLE DB connection information. A Data Link file is identified with the suffix .udl.

To launch this option, select the File Name check box on the Connection page and double-click the button next to the File Name box. (You can also launch the Data Link API in the Database painter by double-clicking the Manage Data Links utility included with the OLE DB interface in the list of Installed Database Interfaces.)

For more information on using the Data Link API, see Microsoft's Universal Data Access website at http://msdn.microsoft.com/en-us/data/default.aspx.

Using a Data Link file versus setting the database parameters

If you use a Data Link file to connect to your data source, all other database-specific settings you make in the ADO.NET Database Profile Setup dialog box are ignored.

Getting identity column values

You can use the standard select @@identity syntax to obtain the value of an identity column. You can also use an alternative syntax, such as select scope_identity(), by adding sections to a .NET configuration file for your application.

Setting up a dbConfiguration section in a configuration file

The following example shows the general structure of a configuration file with a database configuration section and one custom configuration section:

<configuration>
   <configSections>
     <sectionGroup name="dbConfiguration">
        <section name="mycustomconfig"
         type="Sybase.PowerBuilder.Db.DbConfiguration,
         Sybase.PowerBuilder.Db"
        />
      </sectionGroup>
   </configSections>

   <dbConfiguration>
      <mycustomconfig dbParm="optional_value"
       getIdentity="optional_syntax" 
      />
   </dbConfiguration>
</configuration>

To add a database configuration section to a .NET configuration file:

  1. In the <configSections> section of the configuration file, add a <sectionGroup> element with the name "dbConfiguration". This name is case sensitive.

    <configSections> must appear at the beginning of the configuration file, before the <runtime> section if any.

  2. In the dbConfiguration <sectionGroup> element, add one of more <section> elements.

    For each section, specify a name of your choice and a type. The type is the strong name of the assembly used to parse this section of the configuration file.

  3. Close the <section> and <configSections> elements and add a <dbConfiguration> element.

  4. For each section you defined in step 2, add a new element to the <dbConfiguration> element.

    For example, if you defined a section called config1, add a config1 element. Each element has two attributes: dbParm and getIdentity. You can set either or both of these attributes.

    The dbParm value sets the value of the DBParm parameter of the transaction object. It has a maximum length of 1000 characters. If you set a value for a parameter in the configuration file, any value that you set in code or in the Database Profile Setup dialog box is overridden.

    The getIdentity value specifies the syntax used to retrieve the value of an identity column. It has a maximum length of 100 characters. If you do not specify a value for getIdentity, the select @@identity syntax is used.

Sample configuration file

This sample configuration file for PowerBuilder 2019 R3 is called pb190.exe.config. It contains three custom configurations. The <myconfig> element sets both the dbParm and getIdentity attributes. <myconfig1> sets getIdentity only, and <myconfig2> sets dbParm only. The <runtime> section is in the configuration file that ships with PowerBuilder but would not be included in the configuration file that you ship with your application, which would have the same name as your application with the extension exe.config.

<configuration>
   <configSections>
     <sectionGroup name="dbConfiguration">
        <section name="myconfig"
         type="Sybase.PowerBuilder.Db.DbConfiguration,
         Sybase.PowerBuilder.Db"
        />
        <section name="myconfig1"
         type="Sybase.PowerBuilder.Db.DbConfiguration,
         Sybase.PowerBuilder.Db"
        />
        <section name="myconfig2"
         type="Sybase.PowerBuilder.Db.DbConfiguration,
         Sybase.PowerBuilder.Db"
        />
      </sectionGroup>
   </configSections>

<runtime>
      <assemblyBinding xmlns=
       "urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name=
            "Sybase.PowerBuilder.Db"/>
            <codeBase href="file:///C:/Program Files/
             Appeon/PowerBuilder 19.0/DotNET/bin/
             Sybase.PowerBuilder.Db.dll"/>
         </dependentAssembly>
         <dependentAssembly>
           <assemblyIdentity name=
            "Sybase.PowerBuilder.WebService.WSDL"/>
           <codeBase href="file:///C:/Program Files/
            Appeon/PowerBuilder 19.0/DotNET/bin/
            Sybase.PowerBuilder.WebService.WSDL.dll"/>
         </dependentAssembly>
         <dependentAssembly>
           <assemblyIdentity name=
            "Sybase.PowerBuilder.WebService.Runtime"/>
            <codeBase href="file:///C:/Program Files/
             Appeon/PowerBuilder 19.0/DotNET/bin/
             Sybase.PowerBuilder.WebService.
             Runtime.dll"/>
         </dependentAssembly>
         <probing privatePath="DotNET/bin" />
      </assemblyBinding>
   </runtime>
   <dbConfiguration>
      <myconfig dbParm="disablebind=1"
       getIdentity="select scope_identity()"       />
      <myconfig1 getIdentity="select scope_identity()"
      />
      <myconfig2 dbParm=
       "Namespace='Oracle.DataAccess.Client',
       DataSource='ora10gen',DisableBind=1,
       NCharBind=1,ADORelease='10.1.0.301'"       />
   </dbConfiguration>
</configuration>

Specifying the custom configuration to be used

On the System tab page in the Database Profile Setup dialog box for ADO.NET or in code, specify the name of the custom configuration section you want to use as the value of the DbConfigSection parameter. For example:

Sqlca.DBParm="DbConfigSection='myconfig'"

If you set any parameters in the profile or in code that are also set in the configuration file, the value specified in the configuration file takes precedence.

The configuration file must be present in the same directory as the executable file and must have the same name with the extension .config.

Sharing ADO.NET Database Connections

PowerBuilder applications can share database ADO.NET connections with third-party .NET assemblies exposed as COM through a connection proxy. The connection proxy is an instance of type IAdoConnectionProxy.

The IAdoConnectionProxy interface is defined in the Sybase.PowerBuilder.DataSource.Sharing.dll assembly as follows:

IAdoConnectionProxy {
    object Connection; //accepts System.Data.IDbConnection
    object Transaction; //accepts System.Data.IDbTransaction
    event EventHandler TransactionChanged;
}

Both the PowerBuilder application and the third-party assembly manage connections and transactions by referencing the proxy.

The assembly must be registered as COM by using regasm.exe under the Microsoft.NET\Framework\v4.0 folder. Please refer to the Microsoft MSDN library for information about regasm.exe.

The PowerBuilder Transaction object is the standard PowerBuilder nonvisual object used in database connections. To manage the shared connection, the Transaction object references the AdoConnectionProxy object using these methods:

  • bool SetAdoConnection (oleobject connectionProxy) -- accepts an imported ADO.NET connection.

  • oleobject GetAdoConnection() -- accepts an ADO.NET connection exported from the Transaction object.

Importing an ADO.NET Connection from a Third-Party .NET Assembly

You can import an ADO.NET connection from an external .NET assembly into a PowerBuilder application, enabling the application and the assembly to share the connection.

Use the SetAdoConnection method:

bool SetAdoConnection(oleobject proxy)

where proxy is the instance of type IAdoConnectionProxy that is passed in by the third-party assembly.

The imported connection and any transaction are assigned to the IAdoConnectionProxy instance.

The method returns true if the parameter is available (that is, the parameter is an instance of IAdoConnectionProxy or null). It returns false if the operation fails.

Start the connection after invoking SetAdoConnection.

Sample PowerScript Code

//Sample PowerScript code
SQLCA.DBMS = "ADO.NET"
SQLCA.AutoCommit = true
SQLCA.DBParm = "Namespace='System.Data.Odbc', DataSource='SQL Anywhere 11 Demo'"
bool retVal = SQLCA.SetAdoConnection(emp.AdoConnectionProxy)
// emp is an instance of a type in the 3rd-party .NET assembly
if (retVal = true) then
           connect using SQLCA;
           // db operations
end if

Sample C# Code

Here is an example of C# code in the third-party assembly:

public class Emp {
        private IDbConnection conn;
        private IDbTransaction trans;
        ...
        private IAdoConnectionProxy proxy;
        ...
        public object AdoConnectionProxy {
                get {
                        //disposing/clean-up actions.
                        if (null == proxy) {
                                   proxy = new AdoConnectionProxy();
                        }
                        proxy.Connection = conn;
                        proxy.Transaction = trans;
                        return proxy;
                }
                set {
                        //disposing/clean-up actions.
                        proxy = value as IAdoConnectionProxy;
                        if (null != proxy) {
                                if (conn != proxy.Connection as IDbConnection)
                                this.Disconnect(); 
                                conn = proxy.Connection as IDbConnection;
                                trans = proxy.Transaction as IDbTransaction;
                                proxy.TransactionChanged += new
                                                    EventHandler(proxy_TransactionChanged);
                        } else {
                                //disposing/clean-up actions.
                        }
                }
        }
        ...
}

Exporting an ADO.NET Connection to a Third-Party .NET Assembly

To export an ADO.NET connection from a PowerBuilder application, use the GetAdoConnection method:

oleobject GetAdoConnection()

The method returns an instance of IAdoConnectionProxy. The proxy's ADO connection object is assigned to property IAdoConnectionProxy.Connection.

When a transaction starts, the proxy's active Transaction object is assigned to property IAdoConnectionProxy.Transaction, and AutoCommit is false. When AutoCommit is true, the exported IAdoConnectionProxy.Transaction is null..

The method returns null if the connection fails, and false if the operation fails.

To use the shared connection, your third-party assembly must reference the exported connection proxy and manage the transaction. To be notified when the active transaction is changed, you can subscribe the IAdoConnection.TransactionChanged event . Remember to close the connection.

Sample PowerScript Code

//Sample PowerScript code
SQLCA.DBMS = "ADO.NET"
SQLCA.AutoCommit = false
SQLCA.DBParm = "Namespace='System.Data.Odbc', DataSource='SQL Anywhere 11 Demo'"
Connect Using SQLCA;
emp.ConnectionProxy = SQLCA.GetAdoConnection()
// db operations
disconnect using SQLCA;

Sample C# Code

Here is an example of C# code in the third-party assembly:

// Manage the transaction
public class Emp {
             ...
           IAdoConnectionProxy proxy;
           IDbTransaction trans;
             ...
              public object ConnectionProxy {
                get { return proxy; }
                   set {
                                 proxy = value as IAdoConnectionProxy; 
                        ...
                        proxy.TransactionChanged += new
                                                EventHandler(proxy_TransactionChanged);
                   }
        }
        void proxy_TransactionChanged(object sender, EventArgs e) {
                ...
                trans = sender as IDbTransaction;
                ...
           }
        ...
}