Article ID: 910696 - Last Review: November 28, 2007 - Revision: 2.1 Known issues for the ADODB Primary Interop Assembly (PIA) that is included with Visual Studio 2005Caution ADO and ADO MD have not been fully tested in a Microsoft .NET Framework environment. They may cause intermittent issues, especially in service-based applications or in multithreaded applications. The techniques that are discussed in this article should only be used as a temporary measure during migration to ADO.NET. You should only use these techniques after you have conducted complete testing to make sure that there are no compatibility issues. Any issues that are caused by using ADO or ADO MD in this manner are unsupported. For more information, see the following article in the Microsoft Knowledge Base: 840667
(http://support.microsoft.com/kb/840667/
)
You receive unexpected errors when using ADO and ADO MD in a .NET Framework application On This PageINTRODUCTIONThis article describes the known issues for the ADODB Primary Interop Assembly (PIA) that is included with Microsoft Visual Studio 2005. MORE INFORMATIONDifferences in garbage collection between Microsoft Visual Basic 6.0 and Microsoft Visual Basic .NETMajor differences exist between garbage collection in Visual Basic 6.0 and in Visual Basic .NET. The primary difference is that Visual Basic 6.0 garbage collection is more aggressive than Visual Basic .NET garbage collection. With Visual Basic 6.0, as soon as an object instance falls out of scope, the object is immediately released. The same behavior does not occur with Visual Basic .NET or with ordinary .NET garbage collection. With .NET garbage collection, objects are released asynchronously.This difference in garbage collection can have a large effect on your data access code when you move from Visual Basic 6.0 to Visual Basic .NET. For example, an open ADODB Recordset object is closed when the object is reclaimed by garbage collection. Developers who have experience writing Visual Basic 6.0 code may rely on garbage collection semantics that will change when they migrate code to Visual Basic .NET. Because .NET garbage collection is asynchronous and non-deterministic, you may not see the changes even after basic testing occurs. Some databases, such as Microsoft SQL Server 2000 databases, only support a single active result set per connection. If you have a firehose cursor open on a connection to SQL Server, that connection is blocked until the cursor is closed. By default, OLE DB providers will open additional connections to execute queries if the current connection cannot execute that query. Therefore, many ActiveX Data Objects (ADO) users are unaware of this limitation. These additional connections do not participate in connection pooling. Attempts to open additional connections when the blocked connection is participating in a transaction will fail. We recommend that you review your Visual Basic 6.0 code, and explicitly close all Recordset objects and connections. Then, retest your code after you migrate your code to Visual Basic .NET. This section lists three examples of this issue and code examples for each example. Example 1: Additional connections open when you do not explicitly close Recordset objectsWhen you run the following code example in Visual Basic 6.0, only a single connection is required. This is true because the Recordset object that is created in the ExecuteQuery procedure is implicitly closed when the Recordset object falls out of scope. The code example uses the SQL Server @@SPID variable to represent the server process identifier that is used to execute the query. If you run the code, you will notice that the queries return the same value in the @@spid column. This result means that the queries were run on the same connection to the database.This behavior is different because the Recordset object that was created in the ExecuteQuery procedure was not closed and will remain open until the .NET garbage collector cleans up the Recordset object. Garbage collection in the Microsoft .NET Framework occurs asynchronously. If the Recordset object has not been closed by the time that the ExecuteQuery procedure is called again, the SQL Server OLE DB provider will open a new connection to execute the second query. If you add a call to the rs.Close command in the ExecuteQuery procedure, you make sure that the queries are executed on the same connection. You can also explicitly tell the SQL Server OLE DB provider not to open additional connections. To do this, add the following line of code immediately after you open the connection: Example 2: Problems occur when you work with transactions if you do not explicitly close Recordset objectsYou cannot open additional connections when the blocked connection is participating in a transaction. When you run the following code example in Visual Basic 6.0, the code executes multiple queries on a single connection that has an open transaction. The code calls the following two functions:
Cannot create new connection because in manual or distributed transaction mode. Example 3: Problems occur when you implicitly create and then abandon Recordset objectsBy default, the Execute method of the Connection and Command objects implicitly creates and returns a new Recordset object. In Visual Basic 6.0, if this Recordset object is not maintained in an object variable, the Recordset object falls out of scope and is immediately closed. Therefore, the following code example runs successfully in Visual Basic 6.0. However, you will receive the error message that is mentioned in the "Example 2: Problems occur when you work with transactions if you do not explicitly close Recordset objects" section if the code is migrated to Visual Basic .NET.To resolve this problem, pass the adExecuteNoRecords value from the ExecuteOptionsEnum value in the Options parameter of the Execute method. When you do this, you can indicate that the Execute method should not return a Recordset object as illustrated in the following code example. Issue 2: We do not recommend the ADODB PIA for stress scenariosWe strongly discourage you from using the ADODB PIA under stress scenarios, such as in multiuser Microsoft ASP.NET or Microsoft COM+ components. When Microsoft test teams tested the ADODB PIA, the test teams found that the ADODB PIA fails under stress. If .NET data access code must perform reliably under stress, we strongly recommend that you write the code by using ADO.NET.Issue 3: We do not recommend that you use the ADODB PIA in 64-bit modeWe strongly discourage you from using the ADODB PIA in 64-bit applications. The ADODB PIA has not been tested in 64-bit mode. Most 64-bit scenarios involve high-stress server-side components, such as ASP.NET or COM+. The ADODB PIA has known problems running under stress. The limited availability of 64-bit OLE DB providers also makes 64-bit mode less compelling for working with the ADODB PIA.Issue 4: Failures occur when you use late-bound query executionADODB supports two forms of late-bound query execution. Late-bound query execution lets you use the IDispatch binding in COM to execute queries as if the queries were methods on a Connection object. ADODB supports the two following forms of late-bound query execution:
The following examples illustrate these problems. Example 1: If you create a second late-bound query that has the same name, the query failsThe following code example creates two late-bound queries that use the same value for the Name property of the Command object.When similar code is run in Visual Basic .NET, the Command object may not be reclaimed by garbage collection by the time that the second Command object is associated with the Connection object. Therefore, you may receive the following exception error message: Object is already in collection. Cannot append. Example 2: If you call a late-bound query on a second connection, the query failsThe following code example performs the following tasks, in the order in which they are presented:
The Visual Basic .NET compiler does not make this differentiation. On the first call to the "GetCount" query, the Visual Basic .NET compiler caches the method signature in case another call is made to a GetCount method on a Connection object. When the code calls the second "GetCount" query, Visual Basic .NET reuses the cached method signature for the second GetCount method. Because ADODB generates unique method signatures, the call to the second late-bound query fails. No workaround exists for this scenario. Issue 5: You can set some ADODB Variant data types to String data typesThe ADODB object model lets you set some properties either to strings or to other ADODB objects. For example, the ActiveConnection property of the Recordset object appears in the Visual Basic 6.0 Object Browser as a Variant data type and can be set to a Connection object or a connection string.If you have created your own object and want to support this functionality, you must create separate property accessors. To do this, use code that is similar to the following code example.
Issue 6: An InvalidCastException exception occurs when you call the Parameters.Append methodThe ADODB PIA that is included with Microsoft Visual Studio .NET 2003 and Visual Studio 2005 has a known problem that occurs when you call the Parameters.Append method together with a Parameter object that was created by using the default constructor.The following code example will cause an InvalidCastException exception. Issue 7: You experience problems working with components that expect ADO 2.8 interfacesThe ADODB PIA that is included with Visual Studio 2005 is the same component that was included with Visual Studio .NET 2003 and was built by using the Microsoft .NET Framework 1.1. The ADODB PIA was built to interact with ADO 2.7 interfaces and has not been updated to work with ADO 2.8 interfaces.Therefore, attempts to use the ADODB PIA together with components that expose ADO 2.8 interfaces will fail. This scenario is not supported with the ADODB PIA. | Article Translations
|
Back to the top
