将 ADO.NET DataTable 转换为 ADODB.Recordset 的最简单代码






4.79/5 (22投票s)
简单的 C# 代码,用于将 ADO.NET (System.Data) DataTable 转换为 ADODB Recordset。
引言
在使用遗留 ASP 应用程序时,您可能希望将核心业务对象转换为 .NET 类库,同时仍然允许使用现有的 ASP 页面。如果这些页面基于操作 ADODB Recordset
,将它们作为 ADO.NET DataTable
暴露出来可能会非常麻烦。
我看到的现有示例都集中在生成 DataTable
的完全保真副本上,允许更新。在许多情况下,这并不是必需的,并且这些解决方案带来的额外负担和脆弱性是不合理的。
本文是一个快速的代码片段,展示了我认为从 ADO.NET DataTable
转换为 ADODB.Recordset
的最简单方法,然后可以像它仍然来自较旧的中间件组件一样进行处理。
代码
有两个函数,设计为作为某些辅助类中的 static
成员包含在内。主要函数很简单
static public ADODB.Recordset ConvertToRecordset(DataTable inTable)
{
ADODB.Recordset result = new ADODB.Recordset();
result.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
ADODB.Fields resultFields = result.Fields;
System.Data.DataColumnCollection inColumns = inTable.Columns;
foreach (DataColumn inColumn in inColumns)
{
resultFields.Append(inColumn.ColumnName
, TranslateType(inColumn.DataType)
, inColumn.MaxLength
, inColumn.AllowDBNull ? ADODB.FieldAttributeEnum.adFldIsNullable :
ADODB.FieldAttributeEnum.adFldUnspecified
, null);
}
result.Open(System.Reflection.Missing.Value
, System.Reflection.Missing.Value
, ADODB.CursorTypeEnum.adOpenStatic
, ADODB.LockTypeEnum.adLockOptimistic, 0);
foreach (DataRow dr in inTable.Rows)
{
result.AddNew(System.Reflection.Missing.Value,
System.Reflection.Missing.Value);
for (int columnIndex = 0; columnIndex < inColumns.Count; columnIndex++)
{
resultFields[columnIndex].Value = dr[columnIndex];
}
}
return result;
}
一个辅助函数(可以轻松扩展)将 .NET 数据类型映射到正确的 ADODB 字段类型枚举。
static ADODB.DataTypeEnum TranslateType(Type columnType)
{
switch (columnType.UnderlyingSystemType.ToString())
{
case "System.Boolean":
return ADODB.DataTypeEnum.adBoolean;
case "System.Byte":
return ADODB.DataTypeEnum.adUnsignedTinyInt;
case "System.Char":
return ADODB.DataTypeEnum.adChar;
case "System.DateTime":
return ADODB.DataTypeEnum.adDate;
case "System.Decimal":
return ADODB.DataTypeEnum.adCurrency;
case "System.Double":
return ADODB.DataTypeEnum.adDouble;
case "System.Int16":
return ADODB.DataTypeEnum.adSmallInt;
case "System.Int32":
return ADODB.DataTypeEnum.adInteger;
case "System.Int64":
return ADODB.DataTypeEnum.adBigInt;
case "System.SByte":
return ADODB.DataTypeEnum.adTinyInt;
case "System.Single":
return ADODB.DataTypeEnum.adSingle;
case "System.UInt16":
return ADODB.DataTypeEnum.adUnsignedSmallInt;
case "System.UInt32":
return ADODB.DataTypeEnum.adUnsignedInt;
case "System.UInt64":
return ADODB.DataTypeEnum.adUnsignedBigInt;
case "System.String":
default:
return ADODB.DataTypeEnum.adVarChar;
}
}
注意事项
- 您必须在调用
Open
方法之前定义Recordset
中的字段,否则 ADODB 会向您发出错误。 - 这是一个断开连接的
Recordset
,因此不能在没有进一步处理的情况下用于更新表。 - 它仅复制列的“当前”值。
- 它复制所有行,因此请小心处理大型行集。