.net - 手动创建的记录集的行为与断开连接的记录集不同

标签 .net datatable vb6 adodb recordset

我有一个 VB6 应用程序,它将记录集作为其函数之一的参数。我在 .NET 项目中使用 ADODB 创建记录集并将其传递到 VB6 项目。当我通过连接到数据库然后断开连接在 VS2010 中创建记录集时,一切都很好:

con.ConnectionString = "Provider=SQLOLEDB.1;Data Source=MyDB;Initial Catalog=IC;User     ID=user;Password=pass"
rs.ActiveConnection = con
rs.Open("SELECT * FROM Table1")
rs.ActiveConnection = Nothing

但是,当我通过从 .net DataTable 复制数据来创建记录集时: rsRecordSet = 新 ADODB.Recordset

For Each dtDataColumn As DataColumn In dtDataTable.Columns
    Select Case dtDataColumn.DataType.UnderlyingSystemType.ToString
        Case "System.Boolean" : dteRecordSetDataType = DataTypeEnum.adBoolean
        Case "System.Byte" : dteRecordSetDataType = DataTypeEnum.adUnsignedTinyInt
        Case "System.Char" : dteRecordSetDataType = DataTypeEnum.adChar
        Case "System.DateTime" : dteRecordSetDataType = DataTypeEnum.adDate
        Case "System.Double" : dteRecordSetDataType = DataTypeEnum.adDouble
        Case "System.Int16" : dteRecordSetDataType = DataTypeEnum.adSmallInt
        Case "System.Int32" : dteRecordSetDataType = DataTypeEnum.adInteger
        Case "System.Int64" : dteRecordSetDataType = DataTypeEnum.adBigInt
        Case "System.SByte" : dteRecordSetDataType = DataTypeEnum.adTinyInt
        Case "System.Single" : dteRecordSetDataType = DataTypeEnum.adSingle
        Case "System.UInt16" : dteRecordSetDataType = DataTypeEnum.adUnsignedSmallInt
        Case "System.UInt32" : dteRecordSetDataType = DataTypeEnum.adUnsignedInt
        Case "System.UInt64" : dteRecordSetDataType = DataTypeEnum.adUnsignedBigInt
        Case "System.Guid" : dteRecordSetDataType = DataTypeEnum.adGUID
        Case "System.String" : dteRecordSetDataType = DataTypeEnum.adVarChar
        Case Else : dteRecordSetDataType = DataTypeEnum.adVarChar
     End Select
     If dtDataColumn.AllowDBNull Then
        faeRecordSetAttribute = FieldAttributeEnum.adFldIsNullable
     Else
        faeRecordSetAttribute = FieldAttributeEnum.adFldUnspecified
     End If
     rsRecordSet.Fields.Append(dtDataColumn.ColumnName, dteRecordSetDataType, dtDataColumn.MaxLength, faeRecordSetAttribute)
Next

rsRecordSet.CursorLocation = CursorLocationEnum.adUseClient
rsRecordSet.CursorType = CursorTypeEnum.adOpenDynamic
rsRecordSet.LockType = LockTypeEnum.adLockOptimistic
rsRecordSet.ActiveConnection = Nothing
rsRecordSet.Open()

For Each dtDataRow As DataRow In dtDataTable.Rows
     rsRecordSet.AddNew()
     For Each rsField As ADODB.Field In rsRecordSet.Fields
         Select Case rsField.Type
              Case DataTypeEnum.adBoolean : rsField.Value = Convert.ToBoolean(dtDataRow.Item(rsField.Name))
               Case DataTypeEnum.adGUID : rsField.Value = "{" & dtDataRow.Item(rsField.Name).ToString & "}"
               Case Else : rsField.Value = dtDataRow.Item(rsField.Name)
         End Select
     Next
Next

Return rsRecordSet

...我的 VB6 项目立即拒绝它,并出现错误,例如“在此上下文中不允许操作”和“被调用者(服务器 [非服务器应用程序])不可用并消失;所有连接均无效。调用可能已执行。(HRESULT 异常:0x80010007 (RPC_E_SERVER_DIED))”。我也花了一段时间一起调试这两个项目(它在某个时刻起作用),以查看 VB6 项目中记录集被拒绝的位置,但我有一种感觉,它甚至在进入我的 VB6 函数之前就发生了。

我希望有人可以向我解释这两个不同记录集之间的区别。某个记录集中是否有信息表明它曾经连接到数据库源?有没有一种方法可以从现有数据表中“选择”,以便记录集认为它是从某个地方提取的?

提前致谢!

最佳答案

.Net 默认使用断开连接的记录集,但 VB6 则不然。您在代码中打开的记录集是动态记录集,如果没有打开的连接,则无法运行。动态游标类型意味着对记录集的所有更改都会立即发布到数据库中。当您关闭连接后,您就无法再这样做了。您的错误表明,当您尝试添加新记录时,动态游标寻找连接,但找不到连接。

您可能有兴趣检查您的 CursorLocation 是否仍然是 adUseClient。不应该这样;一旦将类型设置为动态,光标就必须位于服务器端。您的光标是静态的,或者您的位置是服务器。

因此,要创建断开连接的记录集,属性必须是:

.CursorLocation = adUseClient  
.CursorType = adOpenStatic 'This is automatic as a result of the previous line
.LockType = adLockBatchOptimistic

这最后与对断开连接的记录集进行批量更改有关,然后在准备好对整个批处理进行锁定时,发布记录,然后执行冲突解决过程。无论如何,看看这是否对你有帮助。应该如此。

多一点:如果您只是将位置设置为客户端,则类型将默认为静态。这是唯一适用于客户端的光标类型。有点道理;如果数据位于客户端,您正在使用数据的本地“快照”。

Here这是 1999 年的一个简单解释,当时这是最前沿的东西。 :)

关于.net - 手动创建的记录集的行为与断开连接的记录集不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23206343/

相关文章:

c# 仅当找到分隔符时才拆分字符串

c# - 如何在gherkin中实现techtalk.specflow中的数据表

vb.net - 自定义错误与自定义异常

vb6 - 禁用列表框VB6中的选定项目

c# - PropertyGrid - 动态加载下拉值

c# - 处理计时器的最佳方法?

c# - C# 枚举标志必须是顺序的吗

c# - 将特定数据从 1 个数据表传输到另一个错误

javascript - 如何为数组中数据表同一列中的每一行提供不同的图标

c# - 加密和解密字符串