将通用数据表转换为类型化数据表

时间:2009-09-09 09:43:27

标签: c# datatable strongly-typed-dataset

我需要重用客户端规定的DataAccess方法。此方法返回vanilla数据表。 我想将这个数据表转换为我的Typed数据表。列数及其类型将匹配。 异常消息“无法将类型为'System.Data.DataTable'的对象强制转换为''类型'MarketValueDataTable'。”  非常清楚,但我该如何解决?

看了casting-a-base-type-to-a-derived-type,但看不出如何做到这一点。

我无法使用datareader填充数据表,只能使用客户端的DataAccess方法。

4 个答案:

答案 0 :(得分:34)

只有当方法返回的表实际上是MarketValueDataTable的实例时,强制转换才有效。如果不是,您所能做的就是将数据复制到MarketValueDataTable的实例。例如,您可以使用Merge方法:

DataTable data = GetData();
MarketValueDataTable myData = new MarketValueDataTable();
myData.Merge(data);

答案 1 :(得分:8)

使用此便捷功能将常规DataTable转换为键入的DataTable

VB

Public Shared Function ConvertToTypedDataTable(Of T As {Data.DataTable, New})(dtBase As Data.DataTable) As T
    Dim dtTyped As New T
    dtTyped.Merge(dtBase)

    Return dtTyped
End Function

用法

Dim dtTyped = ConvertToTypedDataTable(Of dataset1.MyTypedDataTable)(MyUntypedDataTable)

C#

public static T ConvertToTypedDataTable<T>(System.Data.DataTable dtBase) where T : Data.DataTable, new()
{
    T dtTyped = new T();
    dtTyped.Merge(dtBase);

    return dtTyped;
}

用法

dataset1.MyTypedDataTable dtTyped = ConvertToTypedDataTable<dataset1.MyTypedDataTable>(MyUntypedDataTable);

答案 2 :(得分:1)

您无法将DataTable强制转换为MarketValueDataTable,原因很简单,因为它不会从中继承。

您需要做的是实例化一个新的MarketValueDataTable,然后将数据从DataTable复制到其中。

尝试类似:

MarketValueDataTable myTable = new MarketValueDataTable();
StringWriter writer = new StringWriter();
theDataTable.WriteXml(writer);
myTable.ReadXml(new StringReader(writer.ToString()));

(我没有测试过这个)

答案 3 :(得分:0)

如果您的数据表是通用表,则无法将其强制转换为MarketValueDataTable。

您可以尝试的一件事是创建一个新的MarketValueDataTable对象并手动向其添加行。通过单步执行通用数据表的行,然后单步执行每行的列,可以使用反射来设置新MarketValueDataTableRow的属性值。

类似以下内容(警告 - 伪代码):

MarketValueDataTable mv = new MarketValueDataTable();
foreach(DataRow row in table.Rows)
{

   MarketValueDataTableRow mvrow = mv.NewRow();
   foreach(DataColumn col in table.Columns)
   {
      PropertyInfo colProperty = mvrow.GetType().GetProperty(col.Name);
      colProperty.SetValue(mvRow, row[col]);
   }
   mv.Rows.Add(mvrow);

}

你得到了一般的想法。逐步执行泛型表的行并使用反射来查找特定类型数据行中的匹配属性。这应该工作(我之前使用过相同的方法),但必须修改代码以符合您的要求。